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


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
1020
V文字列型変数から指定した一文字のみ削除する。3解決


V

リンク

2012/10/20(Sat) 20:05:00|NO.50107

基本情報技術者午後試験のとある問題のプログラムをHSPで組んでみてます。
その問題におけるプログラムは入力された代入文に文法エラーがないかチェックし、エラーがあればエラーメッセージを表示し終了。
エラーがなければ代入文を変換して表示し終了するといったものです。

問題が起こったのは代入文の文法エラーチェックの部分です。
入力された代入文を一文字ずつ二つの配列S,Vに文字と専用の文字コードを代入していくプログラムなのですが、以下のように組んでみたらstrtrim関数で連続した文字を削除してしまうため代入文を正しく認識することができません。
どのように修正すればいいのかご指摘お願いいたします。
・入力された代入文を配列S,Vに格納するルーチン
 ※専用の文字コード
  S[i]:<< >> 英字 数字 = +,- *,/
  V[i]:0 1 2  3  10 11 12

*ready2analyze if analyzed > 0 : gosub *reset x2 = 10 : y2 = 50 pos x2, y2 strerror = match(eval, "[^-+*/=A-Za-z0-9]", 1) if strlen(strerror) > 0 : goto *error backup = eval cnt_eval = strlen(eval) + 1 repeat cnt_eval if cnt == 0 { S.cnt = "<<" } else { S.cnt = match(eval, "[-+*/=A-Za-z0-9]", 1) code = wpeek(S.cnt, 0) eval = strtrim(eval, 1, code) } if S.cnt == "<<" : V.cnt = 0 if S.cnt == match(S.cnt, "[A-Za-z]") : V.cnt = 2 if S.cnt == match(S.cnt, "[0-9]") : V.cnt = 3 if S.cnt == "=" : V.cnt = 10 if S.cnt == "+" | "-" : V.cnt = 11 if S.cnt == "*" | "/" : V.cnt = 12 loop cnt_eval++ S.cnt_eval = ">>" V.cnt_eval = 1 string = "" val = "" foreach S string += S.cnt loop foreach V if cnt > 0 : val += "/" val += "" + str(V.cnt) loop message = "" + eval + "\n" + string + "\n" + val + "\n\n" analyzed++ goto *analyze



この記事に返信する


cats

リンク

2012/10/20(Sat) 22:10:17|NO.50109

>strtrim関数で連続した文字を削除してしまう
strmidで取り出してはいけないのですか?
やりたいことと違っていたらすみません。



V

リンク

2012/10/21(Sun) 18:38:04|NO.50133

strtrimに気を取られすぎててすっかり気づきませんでしたw
以下のように修正したら思うように動作しました!
解答どうもありがとうございました。


*ready4analyze if analyzed > 0 : gosub *reset x2 = 10 : y2 = 50 pos x2, y2 strerror = match(eval, "[^-+*/=A-Za-z0-9]", 1) if strlen(strerror) > 0 : goto *error backup = eval cnt_eval = strlen(eval) + 1 repeat cnt_eval i = 0 if cnt == 0 { S.cnt = "<<" } else { i = cnt - 1 S.cnt = strmid(eval, i, 1) /* 修正前 S.cnt = match(eval, "[-+*/=A-Za-z0-9]", 1) code = wpeek(S.cnt, 0) eval = strtrim(eval, 1, code) */ } if S.cnt == "<<" : V.cnt = 0 if S.cnt == match(S.cnt, "[A-Za-z]") : V.cnt = 2 if S.cnt == match(S.cnt, "[0-9]") : V.cnt = 3 if S.cnt == "=" : V.cnt = 10 if S.cnt == "+" | "-" : V.cnt = 11 if S.cnt == "*" | "/" : V.cnt = 12 loop S.cnt_eval = ">>" V.cnt_eval = 1 string = "" val = "" foreach S string += S.cnt loop foreach V if cnt > 0 : val += "/" val += "" + str(V.cnt) loop message = "" + eval + "\n" + string + "\n" + val + "\n\n" analyzed++ goto *analyze



ANTARES

リンク

2012/10/21(Sun) 18:40:12|NO.50134

1 文字列を1文字ずつ分解するなどという無駄なことはやめましょう。
 位置を添え字と考えれば、文字列は一種の配列と考えることができます。
 したがって、文字列を分解するのは、実質的に配列を別の配列に
 コピーしているようなものです。
 また、記憶するのは文字そのものではなく位置情報にしましょう。
 位置情報が配列の添え字に対応するものですから。
 演算子・変数名・定数の開始位置のみ記憶すればいいでしょう。

2 match関数は位置情報が得られないので使い物になりません。
 他の関数を使いましょう。
 正規表現関数に位置情報を返すものがあるかどうか知りませんが、
 もし、なければ、1文字ずつ取り出して演算子・変数名・定数の
 いずれであるかを解析するのが現実的だと思います。

3 解析済の文字を削除するのも無駄なことなのでやめましょう。
 文字列操作は時間がかかるので、極力無駄を省くべきです。
 こんなことをせざるを得ないのも、match関数が位置情報を
 返さないせいです。

 なお、1文字を削除するには、instrで位置情報を得て
strmidでその前とその後を取りだし、+で結合します。

 「|」の使い方が間違っています。マニュアルを確認しましょう。



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