初めて質問投稿します。質問に対して不足している情報などあるかもしれませんが、ご容赦ください。
Javaで簡単な計算機の仕組みを作ろうとしています。
しかし、いざコンパイルしようとすると様々なエラーが起こります。
自分は正規表現が間違っているのかなと考えているのですが、
どこがどう間違っているのかわかりません。教えてください。
ちなみに、下記のプログラムはその一部です。
public class Keisan{
public static int clac(String s)throws NumberFormatException, ArrayIndexOutOfBoundsExcepion{
String[] byAry = s.split("");
int c = 0;
int a = Integer.parseInt(brAry[0]);
int b = Integer.parseInt(brAry[2]);
char[] charAry = brAry[1].toCharArray();
if("[+]".equals(charAry)){
c = a + b;
}
else if("[-]".equals(charAry)){
c = a - b;
}
else if("[*]".equals(charAry)){
c = a * b;
}
else if("[/]".equals(charAry)){
c = a / b;
}else{
c = a % b;
}
return c;
}
}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
与えられた "1+2" などの文字列を正規表現で処理するように書き換えました。
この方法の延長では "1 + 2 + 3" や "-1 + 2" などを扱えるようにするのは困難です。
コンパイラの初歩を勉強して、構文解析の手法を使うようにするほうが良いです。
(参考: javacc )
lang
1// See https://teratail.com/questions/4832 2 3import java.util.regex.Pattern; 4import java.util.regex.Matcher; 5 6public class Keisan { 7 8 public String[] parseExperssion(final String str) throws Exception { 9 String[] ans = {"", "", ""}; 10 Pattern p = Pattern.compile("^(?<num1>\d+) *(?<ope>[+|-|*|/|%]) *(?<num2>\d+)$"); 11 Matcher m = p.matcher(str); 12 if (m.matches()) { 13 ans[0] = m.group("num1"); 14 ans[1] = m.group("ope"); 15 ans[2] = m.group("num2"); 16 } else { 17 throw new Exception("Bad expression."); 18 } 19 return ans; 20 } 21 22 public int calc(final String str) throws Exception { 23 String[] terms = parseExperssion(str); 24 // for (String term: terms) { System.out.println(term); } 25 int ans = 0; 26 int a = Integer.parseInt(terms[0]); 27 int b = Integer.parseInt(terms[2]); 28 String ope = terms[1]; 29 30 switch(ope) { 31 default: 32 throw new Exception("bad expression:" + str); 33 case "+": 34 ans = a + b; 35 break; 36 case "*": 37 ans = a * b; 38 break; 39 case "/": 40 ans = a / b; 41 break; 42 case "%": 43 ans = a % b; 44 break; 45 } 46 return ans; 47 } 48 49 public void myTest() { 50 final String[][] TEST_CASES = { 51 {"1 + 2", "3"}, 52 {"2 * 3", "6"}, 53 {"10 / 3", "3"}, 54 {"10 % 3", "1"}, 55 56 {"1+2", "3"}, 57 {"2*3", "6"}, 58 {"10/3", "3"}, 59 {"10%3", "1"}, 60 61 {"1 +2", "3"}, 62 {"1+ 2", "3"}, 63 {"1 + 2", "3"}, 64 65 {"10 / 0", ""}, // 0 で割るとエラー 66 {"10/0", ""}, // 0 で割るとエラー 67 68 // 書式エラー 69 {"", ""}, 70 {"10" , ""}, 71 {"+", ""}, 72 {"10 +", ""}, 73 {"10 + *", ""}, 74 {"10+" , ""}, 75 {"10+*", ""}, 76 {"+ * /", ""}, 77 {"+*/", ""}, 78 {" 1+2" , ""}, 79 {null, ""} 80 }; 81 82 for (String[] test : TEST_CASES) { 83 String exp = test[0]; 84 try { 85 int ans = calc(exp); 86 System.out.println(exp + " = " + ans); 87 if (!test[1].equals("" + ans)) { 88 System.out.println("\tError calc"); 89 } 90 } catch (Exception ex) { 91 System.out.println("'" + exp + "'" + "\n\t" + ex); 92 } 93 } 94 } 95 96 public static void main(String[] args) { 97 Keisan k = new Keisan(); 98 k.myTest(); 99 } 100}
投稿2014/12/28 08:16
編集2018/02/25 12:10総合スコア22322
0
お邪魔します。
ええと、そもそもなのですが、正規表現が誤っていてもコンパイルエラーは発生しませんよ。
実行時にExceptionが発生する可能性はあると思いますが。
それから、calc()メソッド内の引数の扱いも謎です。
Stringで受け取っていますが、期待する入力はどういったものなのでしょうか?
足し算の場合、"1+2"なのか、"1 + 2"なのか。
katoyさんがしれっと直されていますが、String.split()に空文字(="")をregexとして渡しても、
期待したようにbyAry[]には値が入らないと思われます。
その結果
lang
1 int a = Integer.parseInt(brAry[0]); 2 int b = Integer.parseInt(brAry[2]); 3 char[] charAry = brAry[1].toCharArray();
上記のあたりでNullPointerExceptionやNumberFormatExceptionなどが起こると予想されますね。
正規表現といわれていますが、正規表現を使用する箇所はsplitのみで(それには空文字を指定されています)、その他には使用されていませんがどの部分のことをおっしゃっていらっしゃるのでしょうか?
lang
1 if("[\+]".equals(charAry)){ 2 c = a + b; 3 }
と四則演算子と照合をしている部分は単純な比較を行っているに過ぎず、正規表現を使用はしていません。
もし、正規表現を使用するのであれば
lang
1//以下のインポート宣言を追加 2import java.util.regex.Pattern; 3import java.util.regex.Matcher; 4import org.apache.commons.lang.math.NumberUtils; 5 6//クラス内のメソッドで正規表現を扱うサンプル 7String s = "1+2"; 8String regex = "(\d+)(.)(\d+)"; 9Pattern p = Pattern.compile(regex); 10 11Matcher m = p.matcher(s); 12if (m.find()){ 13 int item1 = NumberUtils.toInt(m.group(0)); 14 String operator = m.group(1); 15 int item2 = NumberUtils.toInt(m.group(2)); 16}
こんな感じでしょうか。
自分の趣味でapache commonsのNumberUtilsを使っていますが、使わなくてもいいです。
(NumberUtilsを使う場合はcommons langのjarが必要になるので要注意!)
期待値以外の入力が行われた場合のエラーチェックはちゃんとしてくださいね。
参考まで。
投稿2014/12/28 04:13
総合スコア540
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
コンパイルと簡単な動作チェックができるように書き換えてみました。
(変数名の変更、if での分岐 -> switch での分岐への変更 などをしています。
ここでは exception は細かくは制御していません。すべて Excption にまとめてしまっています。
これは好ましい事ではありません。ぜひ、Excepiton の切り分けを追加してみてください。)
lang
1// See https://teratail.com/questions/4832 2 3public class Keisan { 4 5 public static int calc(final String str) throws Exception { 6 String[] brAry = str.split(" "); 7 // for (String word: brAry) { System.out.println(word); } 8 9 int ans = 0; 10 int a = Integer.parseInt(brAry[0]); 11 int b = Integer.parseInt(brAry[2]); 12 String ope = brAry[1]; 13 14 switch(ope) { 15 default: 16 throw new Exception("bad expression:" + str); 17 case "+": 18 ans = a + b; 19 break; 20 case "*": 21 ans = a * b; 22 break; 23 case "/": 24 ans = a / b; 25 break; 26 case "%": 27 ans = a % b; 28 break; 29 } 30 return ans; 31 } 32 33 public static void myTest() { 34 final String EXPRESSIONS[] = { 35 "1 + 2", // 3 36 "2 * 3", // 6 37 "10 / 3", // 3 38 "10 % 3", // 1 39 40 "10 / 0", // 0 で割るとエラー 41 42 // 書式エラー 43 "", 44 "10", 45 "+", 46 "10 +", 47 "10 + *", 48 null, 49 }; 50 51 for (String exp : EXPRESSIONS) { 52 try { 53 System.out.println(exp + " = " + Keisan.calc(exp)); 54 } catch (Exception ex) { 55 System.out.println("'" + exp + "'" + "\n\t" + ex); 56 } 57 } 58 } 59 60 public static void main(String[] args) { 61 myTest(); 62 } 63}
投稿2014/12/27 23:33
総合スコア22322
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
以下の2つにエラーが出ますね。原因は綴りミスです。
- ArrayIndexOutOfBoundsExcepion
-> ArrayIndexOutOfBoundsException
2. brAry
-> byAry
蛇足のようなもの:千里の道も一歩から。文法を覚え、コンパイルエラーの原因をつかみ、期待どおり動かなければデバッグして間違いの原因をつかみ、色々なアルゴリズムや設計パターンを学ぶ・・・プログラミングは一歩一歩進めていけばよいと思います。
投稿2016/11/03 00:43
総合スコア18392
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
正規表現は使わない上長いですが
恐らくはこういうものを作ろうとしたのではないでしょうか
1.2+3.5
2.5-6.7
3.4*5.6
2.1/7.2
などの書き方で入力すると結果を返すソースです
java
1import java.io.Console; 2 3public class San2{ 4 5public static void main(String[] args){ 6 7Console console=System.console(); 8 9String s=console.readLine("計算式:"); 10 11System.out.println(Keisan2.calc(s)); 12 13} 14 15} 16 17 18class Keisan2{ 19 20public static double calc(String s){ 21 22 23double c1=0; 24double c2=0; 25 26double res=0; 27 28if(s.contains("+")){ 29int ind=s.lastIndexOf("+"); 30 31String s1=s.substring(0,ind); 32String s2=s.substring(ind+1,s.length()); 33 34try{ 35c1=Double.parseDouble(s1); 36c2=Double.parseDouble(s2); 37}catch(Exception e){} 38 39res=c1+c2; 40 41} 42if(s.contains("-")){ 43int ind=s.lastIndexOf("-"); 44 45String s1=s.substring(0,ind); 46String s2=s.substring(ind+1,s.length()); 47 48try{ 49c1=Double.parseDouble(s1); 50c2=Double.parseDouble(s2); 51}catch(Exception e){} 52 53res=c1-c2; 54 55} 56if(s.contains("*")){ 57int ind=s.lastIndexOf("*"); 58 59String s1=s.substring(0,ind); 60String s2=s.substring(ind+1,s.length()); 61 62try{ 63c1=Double.parseDouble(s1); 64c2=Double.parseDouble(s2); 65}catch(Exception e){} 66 67res=c1*c2; 68 69} 70if(s.contains("/")){ 71int ind=s.lastIndexOf("/"); 72 73String s1=s.substring(0,ind); 74String s2=s.substring(ind+1,s.length()); 75 76try{ 77c1=Double.parseDouble(s1); 78c2=Double.parseDouble(s2); 79}catch(Exception e){} 80 81res=c1/c2; 82 83} 84 85 86return res; 87} 88 89 90}
投稿2016/11/02 23:41
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2014/12/28 08:31
2014/12/28 12:02