Kotlin 数值解析器无法处理“10”,并在与 10 相乘时给出 E+
Kotlin numerical parser cannot work with `10` and gives E+ when multiplying with 10
预期输出:3650
我已经用许多数值表达式测试了我的代码,都给出了正确的答案。 只有 10 个造成了所有问题
我的MParser.kt
文件
package com.parser
import java.math.BigDecimal
import java.math.RoundingMode
class MParser(private var mainExp: String) {
var originalExp: String = ""
init {
println(mainExp)
mainExp = mainExp.dePrettify()
originalExp = mainExp
}
fun calc(): String {
calcD()
calcM()
rearrange()
calcA()
calcMi()
if (mainExp==originalExp)
return "Hello"
return mainExp
}
private fun dividable(): MutableList<String> {
val divisible = mutableListOf<String>()
Regex("(\d+\.*\d*)(/+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
divisible.add(it.value)
}
}
return divisible
}
private fun calcD() {
dividable().forEach {
mainExp = mainExp.replace(it, divide(it).toString())
}
}
private fun divide(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("/").toMutableList())
while (num.size > 1) {
val dividend = num[0]
val divisor = num[1]
val quotient = dividend.divide(divisor, 3, RoundingMode.HALF_UP)
num[0] = quotient
num.removeAt(1)
}
return num[0]
}
private fun multiplies(): MutableList<String> {
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\*+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcM() {
multiplies().forEach {
mainExp = mainExp.replace(it, multiply(it).toString())
}
}
private fun multiply(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("*").toMutableList())
while (num.size > 1) {
val factor1 = num[0]
val factor2 = num[1]
val product = factor1 * factor2
num[0] = product
num.removeAt(1)
}
return num[0]
}
private fun addable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\++(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcA() {
addable().forEach {
mainExp = mainExp.replace(it, add(it).toString())
}
}
private fun add(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("+").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 + addend2
num[0] = sum
num.removeAt(1)
}
return num[0]
}
private fun minusable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(-+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcMi() {
minusable().forEach {
mainExp = mainExp.replace(it, minus(it).toString())
}
}
fun minus(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("-").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 - addend2
num[0] = sum
num.removeAt(1)
}
return num[0]
}
/*
Utility -- Methods
*/
private fun rearrange() {
val subtracts = mutableListOf<String>()
Regex("(-(\d+\.*\d*))").apply {
this.findAll(mainExp).forEach {
subtracts.add(it.value)
}
}
subtracts.forEach {
mainExp = mainExp.replaceFirst(it, "")
mainExp += it
}
if (mainExp.startsWith("+"))
mainExp = mainExp.replaceFirst("+", "")
}
fun isParenthesisValid(): Boolean {
var valid = true
val stack = ArrayDeque<Char>()
for (symb in mainExp) {
if (symb == '(' || symb == '[' || symb == '{')
stack.addLast(symb)
else if (symb == ')' || symb == ']' || symb == '}') {
if (stack.isEmpty())
valid = false
else {
val i = stack.removeLast()
if (i == '(' && symb != ')' || i == '{' && symb != '}' || i == '[' && symb != ']')
valid = false
} //end else
}
println("stack: $stack")
} //end for-loop
if (stack.isNotEmpty())
valid = false
return valid
}
private fun String.dePrettify(): String {
return this.replace(" ", "").replace("÷", "/").replace("×", "*")
}
fun optimize(exp: String): String {
return exp.replace(" ", "").replace("÷", "/").replace("×", "*")
}
}
fun toDoubleMutableList(list: MutableList<String>): MutableList<BigDecimal> {
val tempList = mutableListOf<BigDecimal>()
for (i in list) {
val b = BigDecimal(i.toDouble().toString()).stripTrailingZeros()
tempList.add(b)
}
return tempList
}
当我在另一个 .kt file
中执行 val value = try {MParser("365*10").calc()} catch (e: NumberFormatException) {"Error"}
时,我得到 value = 3.65E+3
E+是怎么出现的?
我调试了代码。
我认为问题是从calcMi()
开始的。检查一次,因为我不明白该怎么做。
我测试过并正确的表达式:
//whole numbers
val wexp0 = "12 + 4 - 8 ÷ 2 × 3".optimize() //4
val wexp1 = "7 - 5 + 14 ÷ 2 + 6".optimize() //15
val wexp2 = "37 - 6 × 4 + 32 ÷ 8".optimize() //17
val wexp3 = "64 - 48 ÷ 6 × 4 + 8".optimize() //40
//decimal numbers
val dexp0 = "5*9*69/3/99+45-78*6/3/2-89-4/5+62.2/2/4"
val dexp1 = "-5+4-4+1-78+86-21+9+5-5-1+9.787-2+1000"
val dexp2 = "0.2 + 1.3 - 0.4 × 1.5".optimize() //0.9
val dexp3 = "0.3 × 0.4 - 2.4 ÷ 6 + 1.2 × 4".optimize() //4.52
val dexp4 = "0.72 ÷ 1.2 + 3.5 × 4.2 - 1.6".optimize() //13.7
val dexp5 = "9.2 + 3.5 - 4.9 - 3.5 ÷ 0.7 × 1.2".optimize() //1.8
val dexp6 = "95.01 × 1.2 - 2.4 ÷ 2".optimize() //4.812
但是正如你所看到的,我在上面的任何一个中都没有使用过 10。当我使用 10 时,我突然发现了问题。
请仔细查看调试图像。 10 甚至在乘法完成之前就被转换为 1E+1
。
终于解决了问题
我已经将 minus()
、add()
、multiply()
、divide()
的所有 return 类型更改为 string 而不是保留它 BigDecimal
。
这些方法中的每一个都是 returning BigDecimal
,因此我在输出中得到了 E+。但是我观察到这些方法的所有 returned 值最终都添加到 String
所以在计算之后,我将 toPlainString()
应用于 returned 的 BigDecimal
。
通过这样做,E+ 不会出现在输出中,我也不必一一管理尾随零。
新密码
package com.parser
import java.math.BigDecimal
import java.math.RoundingMode
class MParser(private var mainExp: String) {
var originalExp: String = ""
init {
println(mainExp)
mainExp = mainExp.dePrettify()
originalExp = mainExp
}
fun calc(): String {
calcD()
calcM()
rearrange()
calcA()
calcMi()
if (mainExp==originalExp)
return "Hello"
return mainExp
}
private fun dividable(): MutableList<String> {
val divisible = mutableListOf<String>()
Regex("(\d+\.*\d*)(/+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
divisible.add(it.value)
}
}
return divisible
}
private fun calcD() {
dividable().forEach {
mainExp = mainExp.replace(it, divide(it).toString())
}
}
private fun divide(exp: String): String {
val num = toDoubleMutableList(exp.split("/").toMutableList())
while (num.size > 1) {
val dividend = num[0]
val divisor = num[1]
val quotient = dividend.divide(divisor, 3, RoundingMode.HALF_UP)
num[0] = quotient
num.removeAt(1)
}
return num[0].toPlainString()
}
private fun multiplies(): MutableList<String> {
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\*+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcM() {
multiplies().forEach {
mainExp = mainExp.replace(it, multiply(it).toString())
}
}
private fun multiply(exp: String): String {
val num = toDoubleMutableList(exp.split("*").toMutableList())
while (num.size > 1) {
val factor1 = num[0]
val factor2 = num[1]
val product = factor1 * factor2
num[0] = product.stripTrailingZeros()
num.removeAt(1)
}
return num[0].toPlainString()
}
private fun addable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\++(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcA() {
addable().forEach {
mainExp = mainExp.replace(it, add(it).toString())
}
}
private fun add(exp: String): String {
val num = toDoubleMutableList(exp.split("+").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 + addend2
num[0] = sum
num.removeAt(1)
}
return num[0].toPlainString()
}
private fun minusable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(-+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcMi() {
minusable().forEach {
mainExp = mainExp.replace(it, minus(it).toString())
}
}
fun minus(exp: String): String {
val num = toDoubleMutableList(exp.split("-").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 - addend2
num[0] = sum
num.removeAt(1)
}
return num[0].toPlainString()
}
/*
Utility -- Methods
*/
private fun rearrange() {
val subtracts = mutableListOf<String>()
Regex("(-(\d+\.*\d*))").apply {
this.findAll(mainExp).forEach {
subtracts.add(it.value)
}
}
subtracts.forEach {
mainExp = mainExp.replaceFirst(it, "")
mainExp += it
}
if (mainExp.startsWith("+"))
mainExp = mainExp.replaceFirst("+", "")
}
fun isParenthesisValid(): Boolean {
var valid = true
val stack = ArrayDeque<Char>()
for (symb in mainExp) {
if (symb == '(' || symb == '[' || symb == '{')
stack.addLast(symb)
else if (symb == ')' || symb == ']' || symb == '}') {
if (stack.isEmpty())
valid = false
else {
val i = stack.removeLast()
if (i == '(' && symb != ')' || i == '{' && symb != '}' || i == '[' && symb != ']')
valid = false
} //end else
}
println("stack: $stack")
} //end for-loop
if (stack.isNotEmpty())
valid = false
return valid
}
private fun String.dePrettify(): String {
return this.replace(" ", "").replace("÷", "/").replace("×", "*")
}
fun optimize(exp: String): String {
return exp.replace(" ", "").replace("÷", "/").replace("×", "*")
}
}
fun toDoubleMutableList(list: MutableList<String>): MutableList<BigDecimal> {
val tempList = mutableListOf<BigDecimal>()
for (i in list) {
val b = BigDecimal(i).stripTrailingZeros()
tempList.add(b)
}
return tempList
}
预期输出:3650
我已经用许多数值表达式测试了我的代码,都给出了正确的答案。 只有 10 个造成了所有问题
我的MParser.kt
文件
package com.parser
import java.math.BigDecimal
import java.math.RoundingMode
class MParser(private var mainExp: String) {
var originalExp: String = ""
init {
println(mainExp)
mainExp = mainExp.dePrettify()
originalExp = mainExp
}
fun calc(): String {
calcD()
calcM()
rearrange()
calcA()
calcMi()
if (mainExp==originalExp)
return "Hello"
return mainExp
}
private fun dividable(): MutableList<String> {
val divisible = mutableListOf<String>()
Regex("(\d+\.*\d*)(/+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
divisible.add(it.value)
}
}
return divisible
}
private fun calcD() {
dividable().forEach {
mainExp = mainExp.replace(it, divide(it).toString())
}
}
private fun divide(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("/").toMutableList())
while (num.size > 1) {
val dividend = num[0]
val divisor = num[1]
val quotient = dividend.divide(divisor, 3, RoundingMode.HALF_UP)
num[0] = quotient
num.removeAt(1)
}
return num[0]
}
private fun multiplies(): MutableList<String> {
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\*+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcM() {
multiplies().forEach {
mainExp = mainExp.replace(it, multiply(it).toString())
}
}
private fun multiply(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("*").toMutableList())
while (num.size > 1) {
val factor1 = num[0]
val factor2 = num[1]
val product = factor1 * factor2
num[0] = product
num.removeAt(1)
}
return num[0]
}
private fun addable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\++(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcA() {
addable().forEach {
mainExp = mainExp.replace(it, add(it).toString())
}
}
private fun add(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("+").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 + addend2
num[0] = sum
num.removeAt(1)
}
return num[0]
}
private fun minusable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(-+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcMi() {
minusable().forEach {
mainExp = mainExp.replace(it, minus(it).toString())
}
}
fun minus(exp: String): BigDecimal {
val num = toDoubleMutableList(exp.split("-").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 - addend2
num[0] = sum
num.removeAt(1)
}
return num[0]
}
/*
Utility -- Methods
*/
private fun rearrange() {
val subtracts = mutableListOf<String>()
Regex("(-(\d+\.*\d*))").apply {
this.findAll(mainExp).forEach {
subtracts.add(it.value)
}
}
subtracts.forEach {
mainExp = mainExp.replaceFirst(it, "")
mainExp += it
}
if (mainExp.startsWith("+"))
mainExp = mainExp.replaceFirst("+", "")
}
fun isParenthesisValid(): Boolean {
var valid = true
val stack = ArrayDeque<Char>()
for (symb in mainExp) {
if (symb == '(' || symb == '[' || symb == '{')
stack.addLast(symb)
else if (symb == ')' || symb == ']' || symb == '}') {
if (stack.isEmpty())
valid = false
else {
val i = stack.removeLast()
if (i == '(' && symb != ')' || i == '{' && symb != '}' || i == '[' && symb != ']')
valid = false
} //end else
}
println("stack: $stack")
} //end for-loop
if (stack.isNotEmpty())
valid = false
return valid
}
private fun String.dePrettify(): String {
return this.replace(" ", "").replace("÷", "/").replace("×", "*")
}
fun optimize(exp: String): String {
return exp.replace(" ", "").replace("÷", "/").replace("×", "*")
}
}
fun toDoubleMutableList(list: MutableList<String>): MutableList<BigDecimal> {
val tempList = mutableListOf<BigDecimal>()
for (i in list) {
val b = BigDecimal(i.toDouble().toString()).stripTrailingZeros()
tempList.add(b)
}
return tempList
}
当我在另一个 .kt file
中执行 val value = try {MParser("365*10").calc()} catch (e: NumberFormatException) {"Error"}
时,我得到 value = 3.65E+3
E+是怎么出现的?
我调试了代码。
我认为问题是从calcMi()
开始的。检查一次,因为我不明白该怎么做。
我测试过并正确的表达式:
//whole numbers
val wexp0 = "12 + 4 - 8 ÷ 2 × 3".optimize() //4
val wexp1 = "7 - 5 + 14 ÷ 2 + 6".optimize() //15
val wexp2 = "37 - 6 × 4 + 32 ÷ 8".optimize() //17
val wexp3 = "64 - 48 ÷ 6 × 4 + 8".optimize() //40
//decimal numbers
val dexp0 = "5*9*69/3/99+45-78*6/3/2-89-4/5+62.2/2/4"
val dexp1 = "-5+4-4+1-78+86-21+9+5-5-1+9.787-2+1000"
val dexp2 = "0.2 + 1.3 - 0.4 × 1.5".optimize() //0.9
val dexp3 = "0.3 × 0.4 - 2.4 ÷ 6 + 1.2 × 4".optimize() //4.52
val dexp4 = "0.72 ÷ 1.2 + 3.5 × 4.2 - 1.6".optimize() //13.7
val dexp5 = "9.2 + 3.5 - 4.9 - 3.5 ÷ 0.7 × 1.2".optimize() //1.8
val dexp6 = "95.01 × 1.2 - 2.4 ÷ 2".optimize() //4.812
但是正如你所看到的,我在上面的任何一个中都没有使用过 10。当我使用 10 时,我突然发现了问题。
请仔细查看调试图像。 10 甚至在乘法完成之前就被转换为 1E+1
。
终于解决了问题
我已经将 minus()
、add()
、multiply()
、divide()
的所有 return 类型更改为 string 而不是保留它 BigDecimal
。
这些方法中的每一个都是 returning BigDecimal
,因此我在输出中得到了 E+。但是我观察到这些方法的所有 returned 值最终都添加到 String
所以在计算之后,我将 toPlainString()
应用于 returned 的 BigDecimal
。
通过这样做,E+ 不会出现在输出中,我也不必一一管理尾随零。
新密码
package com.parser
import java.math.BigDecimal
import java.math.RoundingMode
class MParser(private var mainExp: String) {
var originalExp: String = ""
init {
println(mainExp)
mainExp = mainExp.dePrettify()
originalExp = mainExp
}
fun calc(): String {
calcD()
calcM()
rearrange()
calcA()
calcMi()
if (mainExp==originalExp)
return "Hello"
return mainExp
}
private fun dividable(): MutableList<String> {
val divisible = mutableListOf<String>()
Regex("(\d+\.*\d*)(/+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
divisible.add(it.value)
}
}
return divisible
}
private fun calcD() {
dividable().forEach {
mainExp = mainExp.replace(it, divide(it).toString())
}
}
private fun divide(exp: String): String {
val num = toDoubleMutableList(exp.split("/").toMutableList())
while (num.size > 1) {
val dividend = num[0]
val divisor = num[1]
val quotient = dividend.divide(divisor, 3, RoundingMode.HALF_UP)
num[0] = quotient
num.removeAt(1)
}
return num[0].toPlainString()
}
private fun multiplies(): MutableList<String> {
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\*+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcM() {
multiplies().forEach {
mainExp = mainExp.replace(it, multiply(it).toString())
}
}
private fun multiply(exp: String): String {
val num = toDoubleMutableList(exp.split("*").toMutableList())
while (num.size > 1) {
val factor1 = num[0]
val factor2 = num[1]
val product = factor1 * factor2
num[0] = product.stripTrailingZeros()
num.removeAt(1)
}
return num[0].toPlainString()
}
private fun addable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(\++(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcA() {
addable().forEach {
mainExp = mainExp.replace(it, add(it).toString())
}
}
private fun add(exp: String): String {
val num = toDoubleMutableList(exp.split("+").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 + addend2
num[0] = sum
num.removeAt(1)
}
return num[0].toPlainString()
}
private fun minusable(): MutableList<String> {
// 5*9*69/3/99+45-78*6/3/2-89 = sample
val multiplies = mutableListOf<String>()
Regex("(\d+\.*\d*)(-+(\d+\.*\d*))+").apply {
this.findAll(mainExp).toMutableList().forEach {
multiplies.add(it.value)
}
}
return multiplies
}
private fun calcMi() {
minusable().forEach {
mainExp = mainExp.replace(it, minus(it).toString())
}
}
fun minus(exp: String): String {
val num = toDoubleMutableList(exp.split("-").toMutableList())
while (num.size > 1) {
val addend1 = num[0]
val addend2 = num[1]
val sum = addend1 - addend2
num[0] = sum
num.removeAt(1)
}
return num[0].toPlainString()
}
/*
Utility -- Methods
*/
private fun rearrange() {
val subtracts = mutableListOf<String>()
Regex("(-(\d+\.*\d*))").apply {
this.findAll(mainExp).forEach {
subtracts.add(it.value)
}
}
subtracts.forEach {
mainExp = mainExp.replaceFirst(it, "")
mainExp += it
}
if (mainExp.startsWith("+"))
mainExp = mainExp.replaceFirst("+", "")
}
fun isParenthesisValid(): Boolean {
var valid = true
val stack = ArrayDeque<Char>()
for (symb in mainExp) {
if (symb == '(' || symb == '[' || symb == '{')
stack.addLast(symb)
else if (symb == ')' || symb == ']' || symb == '}') {
if (stack.isEmpty())
valid = false
else {
val i = stack.removeLast()
if (i == '(' && symb != ')' || i == '{' && symb != '}' || i == '[' && symb != ']')
valid = false
} //end else
}
println("stack: $stack")
} //end for-loop
if (stack.isNotEmpty())
valid = false
return valid
}
private fun String.dePrettify(): String {
return this.replace(" ", "").replace("÷", "/").replace("×", "*")
}
fun optimize(exp: String): String {
return exp.replace(" ", "").replace("÷", "/").replace("×", "*")
}
}
fun toDoubleMutableList(list: MutableList<String>): MutableList<BigDecimal> {
val tempList = mutableListOf<BigDecimal>()
for (i in list) {
val b = BigDecimal(i).stripTrailingZeros()
tempList.add(b)
}
return tempList
}