質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

1257閲覧

与えられた文字列が、数式として正しいかを判定したい

asyahana

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/05/09 07:47

編集2019/05/09 08:05

与えられた文字列が、数式として正しいかを判定するメソッドを作りたいです。

【条件】
・値として使えるのは、数字(小数含む)、仮数となるax(xは数値)という文字列。
・四則演算記号は「+」「-」「*」「/」
・四則演算記号とは別に、カッコ「(」「)」を使用可能。

考えたサンプルコード(失敗作)

c#

1public bool ValidateCalc(string calcText) 2{ 3 // calcTextを1文字ずつのCharに分解 4 var calcTextCharArray = calcText.ToCharArray(); 5 6 // 1文字ずつloop 7 for (var i = 0; i < calcTextCharArray.Length; i++) 8 { 9 var str = calcTextCharArray[i].ToString(); 10 11 // 数値ならそのまま続ける。 12 if (int.TryParse(str, out int nOut)) { continue; } 13 else 14 { 15 switch (str) 16 { 17 case "a": 18 case ".": 19 // a及びピリオドの場合、後続に数値が来なければ数式として間違っていると見做す。 20 if (i == calcTextCharArray.Length - 1) 21 { 22 return false; 23 } 24 25 var str2 = calcTextCharArray[i + 1].ToString(); 26 if (!int.TryParse(str2.ToString(), out int nOut2)) 27 { 28 return false; 29 } 30 31 break; 32 33 case "+": 34 case "-": 35 case "*": 36 case "/": 37 // 後続に数値,"a","("のいずれかが来なければ数式として間違っていると見做す。 38 if (i == calcTextCharArray.Length - 1) 39 { 40 return false; 41 } 42 43 var str3 = calcTextCharArray[i + 1].ToString(); 44 if (str3 == "a" || str3 == "(" || int.TryParse(str3.ToString(), out int nOut3)) { continue; } 45 else { return false; } 46 47 case "(": 48 var insideKakko = calcText.Substring(calcText.IndexOf("(") + 1, calcText.LastIndexOf(")") - calcText.IndexOf("(") - 1); 49 50 // カッコ内数式を判定。(閉じるカッコがない場合は数式として間違っていると見做す。) 51 if (this.ValidateCalc(insideKakko)) 52 { 53 i = i + insideKakko.Length + 1; 54 continue; 55 } 56 else { return false; } 57 58 default: 59 return false; 60 } 61 } 62 } 63 64 return true; 65}

上記コードでは、

c#

1var testString1 = "a1*a2-(a3+a4/a5+(a6-a7))*8"; // OK 2var testString2 = "2-(a3+a4/a5)*8-(a10%a12)"; // NG

となります。
testString2もOKとなるようにするために、お知恵をお貸しいただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/05/09 08:01

字句解析して構文木を作るのがあらゆる目的に合致しそうです。目的によってはもっと手を抜くことができます。
Zuishin

2019/05/09 08:11

編集後でも testString2 に % が含まれているので当然 NG です。 数値も扱えないし、当然単項マイナス演算子の処理も含まれていません。
k.matsuda

2019/05/09 08:42

すべての return false; にブレークポイントを設定して、デバッグしてみてください。 と思いましたが、開発環境がわからないので、設定できるかどうかわかりませんでしたね。
k.matsuda

2019/05/09 09:20

理由はわかりませんが、var calcTextCharArray = calcText.ToCharArray(); これが、何度も実行されて、テキストが崩れているようです。
guest

回答2

0

testString2もOKとなるようにするために、お知恵をお貸しいただければ幸いです。

ですが、

四則演算記号は「+」「-」「*」「/」

ですので、演算子として通らない%が入っている以上、NGと判定されるのが正解ではないかと思います。

投稿2019/05/09 07:53

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2019/05/09 07:55

コードの誤りとは別件のようですが、初期の条件が正しくないので訂正が必要かと思います。
asyahana

2019/05/09 08:05

すみません、初期条件とコードの誤りを訂正しました。
guest

0

ベストアンサー

どういう目的で作成されているのか分からないので、この回答が適切なのかわかりませんが

C#

1string formulaText = "1+1-(1/1)"; 2double result = (double)(new System.Data.DataTable().Compute(formulaText, ""));

これで文字列の計算が出来ます。
これを利用すればいいのでは?

投稿2019/05/09 08:55

YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問