kotlinで、四則演算のプログラムを書きたいです。

実現したいこと

kotlinで四則演算のプログラムを書きたいです。条件として、掛け算と割り算が足し算と引き算よりも先であること。また、小数点以下もできるだけ正確に表したいということです。

前提

kotlinで四則演算のプログラムを書いています。formulaという変数に数値と演算子(ここでは掛け算の演算子として×を使う)が混ざった文字列を格納します。その後、演算子と数値をリストで分けます。

演算子のリストを順に探索し、×と/があれば、そのインデックスであるi番目と、i+1番目の数値のリストの要素を掛け算、または割り算します。そして、その結果を、i+1番目に更新します。つまり、リストで2つの数値を計算したのち、右側に結果を入れ、左はもう使わないので0にしておきます。

その後、数値リストの0と演算子リストの×と/を消去します。その時に、演算子リストが空であれば、数値リストのi+1番目(演算結果を右側に入れていくので、最後のインデックスに演算結果が入っている)をtotalとして出力します。

まだ、演算子リストの中に+とーが入っていれば、それを計算して、totalとして出力します。

以上がプログラムの流れです。実際に実行してみると、大体の足し算、引き算、掛け算はうまくいきます。問題は割り算です。kotlinにはpythonのように割り算の小数点付きの演算結果を求めてくれる演算子がないため、自力で出さなければいけないのです。(ほかにやり方があれば教えてください。外部ライブラリは今回使いません)

まとめると、小数点以下の演算結果をできるだけ正確に出力したい。また、分母が分子よりも大きい際に発生するエラーをなくしたい。

以上が実現したいことです。

また、分子より分母の方が大きい場合にエラーになります。どうしてエラーになるのかがよくわかりません。(その際のエラーコードを這っておきます)

発生している問題・エラーメッセージ

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) at java.base/java.util.Objects.checkIndex(Objects.java:385) at java.base/java.util.ArrayList.get(ArrayList.java:427) at MainKt.main(Main.kt:35) at MainKt.main(Main.kt)

該当のソースコード

kotlin

1fun main() {2 val formula = "10/100"3 val numbers = formula.split("+", "-", "×", "/").map {it.toInt() }.toMutableList() //数値のみのリスト4 val operator = formula.split("[0-9]+".toRegex()).filter { it.isNotBlank() }.toMutableList() //演算子のみのリスト5 val decimalPointList: MutableList<Double> = mutableListOf() //割り算で出た小数点を、その数字の前の演算子に合わせて符号付きで格納するリスト6 var total = 0.0 //最終的な答え7 8 println(numbers)9 println(operator)10 11 for (i in 0 until operator.size) {12 if (operator[i] == "×") {13 numbers[i + 1] = numbers[i] * numbers[i + 1]14 numbers[i] = 015 } else if (operator[i] == "/") {16 val oldNum = numbers[i + 1] //i番目の演算子の右側の数値を取得しておく17 numbers[i + 1] = numbers[i] / numbers[i + 1] //i番目の演算子の右側を計算結果に更新18 //val decimalPoint: //割り算で出た余りを求めたい19 numbers[i] = 020 if (i > 0) { //始めの演算子が割り算でないのみ(一が割り算だとiが0番目となり、i - 1ができない21 if (operator[i - 1] == "+") { //割り算の前の演算子が+なら正の数22 //decimalPointList.add(decimalPoint)23 } else if (operator[i - 1] == "+") { //割り算の前の演算子が-なら負の数24 //decimalPointList.add(decimalPoint * -1)25 }26 }27 }28 }29 30 numbers.removeAll {it == 0} //リストから0を消去31 operator.removeAll {it == "×"}32 operator.removeAll {it == "/"} //リストから×と/を消去33 34 if (operator.size == 0) { //演算子がすべて*と/だった場合35 total = numbers[0].toDouble()36 println(total)37 }38 39 if (numbers.isNotEmpty()) { //通常時(掛け算・割り算が終わったとき)40 var tmp = 041 for (i in 0 until operator.size) {42 if (operator[i] == "+") {43 tmp = (numbers[i] + numbers[i + 1])44 numbers[i + 1] = tmp 45 } else if (operator[i] == "-") {46 tmp += (numbers[i + 1] * -1)47 numbers[i + 1] = tmp 48 }49 }50 total = tmp.toDouble() + decimalPointList.sum()51 println(total)52 }53}54 55

試したこと

いろいろ試しました。しかし、今回はアルゴリズム系の質問なので、私個人では限界があると感じてしまい質問させていただきました。プログラミング初心者のポンコツ大学生に、皆様お力を貸してください

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

コメントを投稿

0 コメント