HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
0411
GOTOUfor文と配列の使い方11解決


GOTOU

リンク

2008/4/11(Fri) 22:14:54|NO.15057

respの値を、resp(0)から1〜6個繋いで配列配列xに代入し、
次にresp(1)から1〜6個繋いで配列xに代入・・という処理を行い、
xがseq(0)〜seq(3)と同じかどうかをチェックし、
同じならその数を数えるという処理を行いたいのですが、
下記のように1回ずつチェックする以外に、簡単な方法はないでしょうか。

for文を使って試行錯誤していますが、
配列の理解が誤っているのか、上手くカウントされません・・・


screen scrExp, ginfo_dispx, ginfo_dispy, 4, 0, 0;窓枠付き sdim x,100 sdim resp,10 resp(0) = "1" resp(1) = "0" resp(2) = "0" resp(3) = "1" resp(4) = "0" resp(5) = "1" resp(6) = "0" resp(7) = "1" resp(8) = "0" resp(9) = "1" sdim seq,12 seq(0) = "00" seq(1) = "01" seq(2) = "10" seq(3) = "11" for j,0,9 x(num) ="" k = j+6 if k > 9{;respの最大値よりも大きくなったら、おしまい _break   } for i, j, k   x(num) = x(num) + resp(i) if x(num) = seq(0){ seq0++ } if x(num) = seq(1){ seq1++ } if x(num) = seq(2){ seq2++ } if x(num) = seq(3){ seq3++ } mes x(num) next next mes seq(0)+" " + seq0 mes seq(1)+" " + seq1 mes seq(2)+" "+ seq2 mes seq(3)+" "+ seq3



この記事に返信する


ANTARES

リンク

2008/4/12(Sat) 01:15:23|NO.15058

 まず、全角スペースが2カ所にあります。
うち、1個はコンパイルエラーを起こしますから、
一度も実行していないスクリプトですね。
実行したスクリプトをそのまま貼りつけてください。
ちょっとでも直したら、勘違いやタイプミスのために
話が通じなくなる可能性があります。

>sdim x,100
 これは配列ではありません。ヘルプを読み直しましょう。

 また、何か根本的な勘違いがあるようです。
わかりやすくするために要素数は2個にします。

sdim x,100,2

for i,0,2
x(num)=""
next

これは
x(0)=""
x(0)=""
と同じです。numはずっと0なので。

x(0)=""
x(1)=""
としたいのなら

for i,0,2
x(i)=""
next
とする必要があります。



GOTOU

リンク

2008/4/12(Sat) 15:45:08|NO.15061

ANTARES 様

ご指摘有り難うございます。
投稿する際に、修正した時に全角スペースが入り込んでしまったようです。
実行したスクリプトは下記の通りです。

>sdim x,100
>これは配列ではありません。ヘルプを読み直しましょう。

ヘルプより
sdim a,5000 ; 変数aは5000文字ぶんのメモリをあらかじめ確保します
上の例では、変数aは5000文字ぶんのメモリを確保し配列変数にはなりません。

駄目な例を、sdimの例だと思い込んでいました。
>sdim x,100,2
とする必要があるのですね・・・
p2の「文字列のデフォルト文字数」は、
dimで言う所のx(0)〜x(100)まで、という意味でしょうか。


screen scrExp, ginfo_dispx, ginfo_dispy, 4, 0, 0;窓枠付き sdim x,100 sdim resp,10 resp(0) = "1" resp(1) = "0" resp(2) = "0" resp(3) = "1" resp(4) = "0" resp(5) = "1" resp(6) = "0" resp(7) = "1" resp(8) = "0" resp(9) = "1" sdim seq,12 seq(0) = "00" seq(1) = "01" seq(2) = "10" seq(3) = "11" seq(4) = "000" seq(5) = "001" seq(6) = "011" seq(7) = "111" seq(8) = "100" seq(9) = "110" seq(10) = "101" seq(11) = "010" for j,0,9 x(num) ="" k = j+6 if k > 9{;dataの最大値よりも大きくなったら、おしまい _break } for i, j, k x(num) = x(num) + resp(i) if x(num) = seq(0){ seq0++ } if x(num) = seq(1){ seq1++ } if x(num) = seq(2){ seq2++ } if x(num) = seq(3){ seq3++ } mes x(num) next next mes seq(0)+" " + seq0 mes seq(1)+" " + seq1 mes seq(2)+" "+ seq2 mes seq(3)+" "+ seq3



GENKI

リンク

2008/4/12(Sat) 23:03:43|NO.15063

numを修正してないのは配列変数がよく分かってないから…と理解しておきます。

> >sdim x,100,2
> とする必要があるのですね・・・
> p2の「文字列のデフォルト文字数」は、
> dimで言う所のx(0)〜x(100)まで、という意味でしょうか。

sdim x,100,2 x(0)="…(100文字)…" x(1)="…(100文字)…" ;x(2)以降の分は確保できてない。
100文字分の領域を2つ確保する、という意味です。


> 配列の理解が誤っているのか、上手くカウントされません・・・

そもそも何がやりたいのか今ひとつよく分かりませんが、
プログラムそのものは、作られているとおりにきちんとカウントされていますよ。
ちょっとだけスクリプト整理して、コメント入れておきましたので見てみてください。

screen 0, , 700 ;提示されたものはウィンドウ広げすぎ。 sdim x,100 ;100文字分を1個確保 sdim resp,1,10 ;1文字を10個確保 resp(0) = "1" resp(1) = "0" resp(2) = "0" resp(3) = "1" resp(4) = "0" resp(5) = "1" resp(6) = "0" resp(7) = "1" resp(8) = "0" resp(9) = "1" sdim seq,2,4 ;2文字を4個確保 seq = "00", "01", "10", "11" ;こういう書き方も出来ます。 for j,0,9 x ="" k = j+6 ;dataの最大値よりも大きくなったら、おしまい if k > 10 : _break ;resp(9)まであるのでkは10までいけます。理由はfor命令のマニュアル熟読。 for i, j, k x = x + resp(i) a = "" if x = seq(0) : seq0++ : a="←★カウント!" if x = seq(1) : seq1++ : a="←★カウント!" if x = seq(2) : seq2++ : a="←★カウント!" if x = seq(3) : seq3++ : a="←★カウント!" mes x + a ;一致したところで、「←★カウント!」と表示する。 next mes "-------------------" ;見やすくするため区切り線 next ;結果表示 pos 200,0 mes seq(0)+"は、" + seq0 + "個" mes seq(1)+"は、" + seq1 + "個" mes seq(2)+"は、" + seq2 + "個" mes seq(3)+"は、" + seq3 + "個"

まずは紙とエンピツを持って、フローチャートを書いてみることをお勧めします。
次にスクリプトを見て、処理の流れを追いかけてみてください。

----
正直HSPではfor命令初めて使いました。w
ふだんはrepeat命令だけなので。



ANTARES

リンク

2008/4/13(Sun) 00:36:14|NO.15064

>p2の「文字列のデフォルト文字数」は、
>dimで言う所のx(0)〜x(100)まで、という意味でしょうか。
 p2はGENKIさんも書いているように、1要素の大きさです。
x(0)やx(1)には100バイトのメモリが割り当てられるということです。
言い換えるとx(0)には99バイトまでの文字列しか代入できないということです。

 正確にはそれ以上の文字列を代入できる場合もありますが、
ややこしくなるのでその話は割愛します。
また、なぜ100でなくて99なのかという話も割愛します。
興味があるなら「HSP3文字列のひみつ(中級者向け) (hsp3str.htm)」を
読んでください)

>for j,0,9
> x(num) =""
 numには何も値を代入していませんが、そのような場合、
HSPは自動的に0を代入します。したがって、numの値はは10回とも0です。
つまり、x(num)は10回ともx(0)を意味するので
x(0)=""
を10回繰り返していることになります。

x(0)=""
x(1)=""
x(2)=""
 .
 .
 .
x(9)="
にしたければ、
for j,0,9
  x(j) =""
とする必要があります。



GOTOU

リンク

2008/4/13(Sun) 01:29:29|NO.15065

GENKI 様
配列の説明と、スクリプトの修正有り難うございます。
可成整理されて、わかりやすくなりました。

>そもそも何がやりたいのか今ひとつよく分かりませんが、
>プログラムそのものは、作られているとおりにきちんとカウントされていますよ。

実際にこのスクリプトを使う場面では、
1か0のユーザーからの入力に、特定の組み合わせ(パターン)が、
どれくらい含まれているかを調べます。
パターンも、1と0の組み合わせが2個〜6個まで用意するので、
124個あるため、if文を124個用意するよりは、
for文でseq(0)〜seq(123)までチェックするようにしたいのです。

ご指摘頂いたように、配列の理解が間違っていたので、
フローチャートを用意して、もう一度作り直してみます。

ANTARES 様
丁寧にご説明頂き、有り難うございます。
今回のスクリプトの場合は短いので、
x(0)〜x(29)まで、30個用意すれば良いと判るのですが、
何個用意したら良いか判らない場合は、
for文の中で無理に使わない方が良さそうですね・・・



GENKI

リンク

2008/4/13(Sun) 11:50:43|NO.15067

> また、なぜ100でなくて99なのかという話も割愛します。

すみません。しゅうりょうこーどのこと忘れてました。
訂正します。
sdim x,100,2
x(0)="…(99文字)…" x(1)="…(99文字)…" ;x(2)以降の分は確保できてない。
99文字分の領域を2つ確保する、という意味です。
詳細は「HSP3文字列のひみつ」参照のこと。

私が提示したsdim命令の第2パラメータは全部+1してください。
例「sdim resp,1,10」→「sdim resp,2,10」
間違っててもちゃんと動作するのは自動確保されたためです。


> x(0)〜x(29)まで、30個用意すれば良いと判るのですが、

本当に必要ですか?
今回のスクリプトでもxは1個しか必要ありませんよ。
一応…、何個用意したら良いか判らない場合は、必要以上に多めに確保しておくという手もあります。
しかしよく考えて作るにこしたことはありません。




そういえば文字列操作関数とか使えそうな気も…。



ANTARES

リンク

2008/4/14(Mon) 03:09:17|NO.15097

>respの値を、resp(0)から1〜6個繋いで配列配列xに代入し、
>次にresp(1)から1〜6個繋いで配列xに代入・・という処理を行い、
>xがseq(0)〜seq(3)と同じかどうかをチェックし、
>同じならその数を数えるという処理を行いたいのですが、

>パターンも、1と0の組み合わせが2個〜6個まで用意するので、

No.15061のスクリプトも考慮して、以下のスクリプトになります。
ただし、xは配列にする必然性がないので単純変数にしています。


maxcnt=6 ;繋ぐ個数の最大値 maxcnt2=maxcnt+1 nresp=10 sdim resp,2,nresp resp="1","0","0","1","0","1","0","1","0","1" nseq=12 sdim seq,maxcnt+1,nseq seq= "00","01","10","11","000","001","011","111","100","110","101","010" dim cn,nseq ;cn(i):seq(i)が何個あったか for i,0,nresp-1 ;i:resp()の何番目から繋ぐか if i+maxcnt>nresp { m=nresp-i+1 } ;6個繋げないとき else { m=maxcnt2 } ;6個繋げるとき for j,2,m ;j:何個繋ぐか ;resp(i)からj個繋いでxに格納 x="" for k,i,i+j x+=resp(k) next ;カウント for k,0,nseq if x==seq(k): cn(k)++ next next next ;結果表示 for i,0,nseq mes seq(i)+" "+cn(i) next



ANTARES

リンク

2008/4/14(Mon) 03:09:52|NO.15098

>パターンも、1と0の組み合わせが2個〜6個まで用意するので、
>124個あるため、if文を124個用意するよりは、

 124個のseq()を作るスクリプトです。


sdim seq,7,124 bmask=2 m=0 x=0 y=0 for i,2,7 bmask=bmask<<1 ;bmask=bmask*2あるいはpower bmask,2,iと同じ for j,0,bmask ;jを2進数i桁に変換 d=j for k,0,i seq(m)=""+(d&1)+seq(m) d=d>>1 ;d=d/2と同じ next ;seq()の表示 pos x,y: mes "seq("+m+")="+seq(m) m++ y+=16 if y+16>ginfo_winy { x+=128 y=0 } next next



GOTOU

リンク

2008/4/15(Tue) 00:52:23|NO.15111

GENKI 様
有り難うございます。
>私が提示したsdim命令の第2パラメータは全部+1してください。
上記了解致しました。

>今回のスクリプトでもxは1個しか必要ありませんよ。
色々検討してみた所、確かに1個しか必要ありませんでした。

ANTARES 様
有り難うございます。
昨晩試行錯誤して、124個のseqを作り、
別ファイルから読み込むように作りました。
ちょっと長い上に、データファイルと、
seqのパターンを書いたファイルが無いと動きませんが・・・


notesel data num = ●;データ数 num_count_s = ●;開始 num_count_e = ●;最終 num_end = num_count_e + 1 num_p = num * 10 sdim seq_p,6,125 dim seq,125 sdim resp,1,●;ファイルから読み込むデータ ;respに1文字分を21個 sdim resp_p,6,num_p;系列のパターン sdim rft,2,num_p sdim x,6,2 #include "hsp3util.as" arrayload "seq_pattrn.txt",seq_p;系列のパターンはseq_p(0)からseq_p(123)の124種類 arrayload "データファイル名",resp for i, 0, num_count_e resp_p(i)=strmid(resp(i),0,1);pに左か右の値を代入 next ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;分析用データの抽出完了 for j,num_count_s,num_count_e;取り出す起点を決める。 x ="" y = 0 if j > num_count_s{ j = j + 5 } k = j+6 if k > num_end{;dataの最大値よりも大きくなったら、おしまい _break } for i,j,k;iのj番目から6文字目まで文字を繋ぐ x = x + resp_p(i) y = y + rft(i) for h,0,123;seq_pをチェック if x = seq_p(h){;同じパターンがあれば、数を数える seq(h)++ mes x data +="\n" +x +" "+seq(h) +" "+y } next next mes "-------------------" ;見やすくするため区切り線 data += "\n-------------------" ;見やすくするため区切り線 next ;data += "\n-------------------" ;見やすくするため区切り線 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;data_save.txtから毎回コピペ notesave "seq_data.dat" data +="\n" + seq_p(0)+" "+seq(0) +" data +="\n" + seq_p(1)+" "+seq(1) +" data +="\n" + seq_p(2)+" "+seq(2) +" ;中略 data +="\n" + seq_p(123)+" "+seq(123) +"



ANTARES

リンク

2008/4/16(Wed) 00:07:14|NO.15134

> if j > num_count_s{
> j = j + 5
> }
 これは何ですか?



GOTOU

リンク

2008/5/1(Thu) 16:15:08|NO.15564

過去ログをチェックしていたら、
解決チェックを入れ忘れていたことに気づきました。
申し訳ございません。

ANTARES 様
> if j > num_count_s{
> j = j + 5
> }
ご指摘有り難うございます。
上記は不必要な部分でした。
完成版からは削除しています。



ONION software Copyright 1997-2021(c) All rights reserved.