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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

3319閲覧

java初心者の質問です

kurageno

総合スコア16

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2015/10/10 06:35

編集2015/10/10 09:36

学校の課題で電卓?の作成をしています。
式をユーザーが入力をして実行すると答えがでる というものです。
例えば
ユーザー入力)1 + 8 - 4 * 2
答えは10
という形のものです。ただし計算の順番は無視するものとする。 というものなのですが 僕の作ったソースだと
1 + 8 - 4 * 2
答えは2
という風になってしまします。
これを計算できるようにしていきたいのですがどうソースを書いたらいいのか教えてください。
あと 計算の順番を掛け算割り算からするとしたらどうしたらいいでしょうか?
やりたいことは入力された値を保持してあとから取り出す....ということをしたいです。
参考にソースなどを書いて下さるとわかりやすいです。
お願いします。

↓ソース

import java.io.*;

class Keisanki
{
public static void main(String[] args) throws IOException
{

int answer = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("式を入力してください"); String siki = br.readLine();//文字列を分割する必要がある。 String[] keisan = siki.split(" "); String en = "a";//演算子が入力された時に保存する場所 String num,num1;//数字が入力された時に保存する変数の宣言 int i = 0; num ="";//数字が入力された時に保存する場所(左辺) num1 = "";//数字が入力された時に保存する場所(右辺) for ( i = 0; i < keisan.length; i++) {//iの数だけ繰り返される(ループ) //System.out.println(keisan[i]);//ここで出力されるものはlengthで返ってくるもの if ( i % 2 == 0 ) { num = Integer.parseInt(keisan[i]); } else { en = keisan[i];//奇数の時は演算子 //System.out.println("演算子" + en); } if ( i == 0 ) { num1 = Integer.parseInt(keisan[i]); } } if (i % 2 != 0 && i != 1){ if(en.equals("+")){ answer = num1 + num; } else if(en.equals("-")){ answer = num1 - num; } else if(en.equals("*")){ answer = num1 * num; } else if(en.equals("/")){ answer = num1 / num } } System.out.println("答えは" + answer + "です"); }

}

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

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

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

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

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

guest

回答3

0

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/11 08:54

katoy

総合スコア22324

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

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

kurageno

2015/10/12 06:05

とてもわかりやすく そしてコードもありがとうございます。 優先順位なしのはできたので、優先順位ありのものをつくってみます。 本当にありがとうございます。
katoy

2015/10/12 08:22

どんな式をつかってテストしたらプログラムのバグを発見できるか? についても検討して、 テストをするプログラムを書くことにおついても勉強をするとよいと思います。
guest

0

>計算の順番を掛け算割り算からするとしたらどうしたらいいでしょうか?

電卓にMR,M+,M-というボタンが有るでしょ。
加減乗除しかないとしたら加算と減算はそのまま計算し、乗算除算が出てきたら
結果を一旦キープして乗除を計算してその結果とキープを計算するといいでしょう。

投稿2015/10/10 07:44

maiko0318

総合スコア876

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

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

kurageno

2015/10/12 06:04

回答頂きありがとうございます! 参考にさせていただきます。
guest

0

ベストアンサー

String型で宣言しているnum,num1にparseIntの結果を代入しているのが解せないのですが・・・これらはint型であると仮定して話を進めます.
このコードを順番に解釈していくと
0. 入力をスペース区切りでString配列に変換
0. for文で,最初の要素をnumに,それ以降演算子はenに,数値はnum1に代入する.
0. forを抜けた後,enに入っている演算子によってnumとnum1を計算する
ここで問題なのは2.で,forでループする間enとnum1は更新を繰り返します.結局例の場合ではnumには最初の数字である1が,enには最後の演算子"",num1には最後の数字2が入り,計算は
1
2 = 2
という結果になります.
電卓のような動作をさせるのですから,演算子が入力されるたびに,その前に入力された演算子に応じた計算をしないとおかしくなります.つまり,forループの中で計算をしないといけません.

投稿2015/10/10 07:06

swordone

総合スコア20651

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

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

kurageno

2015/10/10 09:50

回答頂きありがとうございます。 for文でループする間enとnum1の更新が繰り返すのはわかりました。 二つ分からないことがありまして、 1 更新されてしまって最初と最後の計算しかできないのでその間の計算をさせるためにはどうしたらいいでしょうか? 2 今はi = 0 と仮定して一番目の計算はできていますが、それをi = 0でないときも計算させるためにはどうしたらいいでしょうか? お手数おかけしますが、 ソースの書き方などもわからないので教えてください。
swordone

2015/10/10 09:59

1. 電卓をイメージしてください.+-×÷の記号を入れた時,その前に入れた数字と記号で計算した結果が画面に表示されるはずです.それをこのコードで再現します. そのためには,記号(上で言う演算子)が入力された時,すなわちもとのコードでenに代入する段階で,代入の前に計算(最後のif (i % 2 != 0 && i != 1)ブロックでやっていること)をする必要があります. 2. すみませんが.質問の意味がわかりません.「i =0と仮定して」というのはどこの話でしょうか?
kurageno

2015/10/10 10:17

回答頂きありがとうございます。 1はわかりました。 計算をするタイミングがわかっていませんでした。 2は if ( i == 0 ) { num1 = Integer.parseInt(keisan[i]); } の箇所です。 そもそもStringで宣言しているものをintに変換することが無意味なのでしょうか?
swordone

2015/10/10 12:03

計算するのでintへの変換は必要です.しかし変換してintになった値をString型の変数に入れることは無理です.私が言いたいのはnum,num1の宣言の型が違うということです. ご提示のコードはコンパイルが通らないのでは?
kurageno

2015/10/10 15:51

回答頂きありがとうございます。 ようやく理解ができました。 なおしてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問