2つの計算メソッドを書いてみました。
1つは 質問文のものを少し変更したもので、演算の優先度は無視して計算をするものです。
もう1つは、掛け算割り算を優先的に計算するものです。
以下の往路グラムでは、式として空行入力をするまでは、繰り返し2つの計算結果を示します。
java
1import java.io.BufferedReader;
2import java.io.IOException;
3import java.io.InputStreamReader;
4import java.util.Stack;
5
6class Keisanki {
7 public static void main(String[] args) throws IOException {
8
9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
10 while (true) {
11 System.out.println("式を入力してください。(空行を入力すると終了)");
12 String siki = br.readLine().trim(); // 文字列を分割する必要がある。
13 if (siki.length() == 0) { // 空行なので終了する
14 break;
15 }
16
17 System.out.println("答えは " + calc0(siki) + " です。[演算の優先度は無視]");
18 System.out.println("答えは " + calc(siki) + " です。[演算の優先度を考慮]");
19 }
20 }
21
22 // 演算の優先度を無視して計算する。
23 static int calc0(String siki) {
24 String[] keisan = siki.split(" ");
25 int answer = Integer.parseInt(keisan[0]);
26 String op = null;
27 for (int i = 1; i < keisan.length; i++) {
28 if (i % 2 == 1) { // 奇数の時は演算子
29 // TODO: en が +, - * / のいずれかであることをチェックすること
30 op = keisan[i];
31 } else { // 偶数の時は数字
32 // TODO: keisan[i] が数字であることをチェックすること。
33 int num = Integer.parseInt(keisan[i]);
34 if (op != null) {
35 answer = calc_simple(answer, num, op);
36 }
37 op = null;
38 }
39 }
40 return answer;
41 }
42
43 // 演算の優先度を考慮して計算する
44 static int calc(String siki) {
45 String[] keisan = siki.split(" ");
46 Stack<Integer> nums = new Stack<Integer>();
47 Stack<String> ops = new Stack<String>();
48
49 for (int i = 0; i < keisan.length; i++) {
50 if (i % 2 == 1) { // 奇数の時は演算子
51 String op = keisan[i];
52 if (ops.size() > 0 && nums.size() > 1) {
53 String op0 = ops.peek();
54 // 1つ前の演算が * か / , または 1つ前と今の演算が +か - なら, すぐに計算をする。
55 if ("*/".indexOf(op0) != -1 || ("+-".indexOf(op0) != -1 && "+-".indexOf(op) != -1)) {
56 int num1 = nums.pop();
57 int num0 = nums.pop();
58 String opx = ops.pop();
59 int result = calc_simple(num0, num1, opx);
60 nums.push(result);
61 }
62 }
63 ops.push(op);
64 } else { // 偶数の時は数字
65 nums.push(Integer.parseInt(keisan[i]));
66 }
67 }
68
69 while (!ops.isEmpty()) {
70 int num1 = nums.pop();
71 int num0 = nums.pop();
72 String op = ops.pop();
73 int result = calc_simple(num0, num1, op);
74 nums.push(result);
75 }
76 // nums.size() == 1 であることをチェックすること。
77 return nums.pop();
78 }
79
80 // "num0 op num1" の式を計算する。
81 static int calc_simple(int num0, int num1, String op) {
82 int ans = num0;
83 if ("+".equals(op)) {
84 ans += num1;
85 } else if ("-".equals(op)) {
86 ans -= num1;
87 } else if ("*".equals(op)) {
88 ans *= num1;
89 } else if ("/".equals(op)) {
90 // TODO: num != 0 をチェックすること
91 ans /= num1;
92 }
93 return ans;
94 }
95}
96// 演算の優先度を考慮した時の計算例
97// 2 -> 2
98// 2 + 3 -> 5
99// 2 * 3 -> 6
100// 2 / 3 -> 0
101//
102// 2 + 3 * 4 * 5 -> 62
103// 2 * 3 + 4 * 5 -> 26
104// 2 * 3 * 4 + 5 -> 29
105//
106// 2 - 3 + 4 + 5 -> 8
107// 2 + 3 - 4 + 5 -> 6
108// 2 + 3 + 4 - 5 -> 4
109//
110// 2 + 3 + 4 + 5 -> 14
111// 2 * 3 * 4 * 5 -> 120
112// 120 / 3 / 4 / 5 -> 2
113// 120 / 3 + 4 / 2 -> 42
114// TODO
115// (, ), 単項演算をサポートすること。
116// 空白で区切らなくても済むようにすること。
実行例
式を入力してください。(空行を入力すると終了)
2 + 3 * 4 * 5
答えは 100 です。[演算の優先度は無視]
答えは 62 です。[演算の優先度を考慮]
式を入力してください。(空行を入力すると終了)
2 * 3 + 4 * 5
答えは 50 です。[演算の優先度は無視]
答えは 26 です。[演算の優先度を考慮]
式を入力してください。(空行を入力すると終了)
2 * 3 * 4 + 5
答えは 29 です。[演算の優先度は無視]
答えは 29 です。[演算の優先度を考慮]
式を入力してください。(空行を入力すると終了)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/10/12 06:05
2015/10/12 08:22