Utilicé el siguiente código de un hilo diferente para resolver las expresiones aritméticas de cadenas en mi aplicación de Android Kotlin . Funciona la mayor parte del tiempo, pero identifiqué que da error para algunas expresiones. A continuación hay algunos de ellos.
((4 - 12) - 4) - 14 ((9 - 7) - 19) - 4 ((8 - 10) - 6) - 11 ((2 - 5) * 16) - 3 ((6 - 15) - 5) / 15
import kotlin.math.pow fun basic(rightNum:String?, leftNum:String?, op:String?):Double? { return when (op) { "+" -> { (rightNum?.toDouble()!! + leftNum?.toDouble()!!) } "-" -> { (rightNum?.toDouble()!! - leftNum?.toDouble()!!) } "*" -> { (rightNum?.toDouble()!! * leftNum?.toDouble()!!) } "^" -> { ((rightNum?.toDouble()!!).pow(leftNum?.toDouble()!!)) } else -> { (rightNum?.toDouble()!! / leftNum?.toDouble()!!) } } } fun elemInside(mainString:String?, listCheck:List<String>):Boolean { for (ops in listCheck) { if (mainString?.contains(ops)!!){ return true } } return false } fun getOpIndex(query: String?, operations:List<String>):Array<Int> { var allIndex:Array<Int> = arrayOf() var dupQuery = query while (elemInside(dupQuery, operations)) { for (op in operations) { if (dupQuery?.contains(op)!!) { allIndex = allIndex.plusElement(dupQuery.indexOf(op)) dupQuery = dupQuery.substring(0, dupQuery.indexOf(op)) + '1' + dupQuery.substring(dupQuery.indexOf(op) + 1) } } } allIndex.sort() return allIndex } fun parseSimple(query:String?):Double? { val operations = listOf("^", "/", "*", "-", "+") var allIndex: Array<Int> = arrayOf() var calcQuery = query while (elemInside(calcQuery, operations) && (allIndex.size > 1 || if (allIndex.isEmpty()) true else allIndex[0] != 0)) { for (op in operations) { calcQuery = calcQuery?.replace("-+", "-") calcQuery = calcQuery?.replace("--", "+") calcQuery = calcQuery?.replace("+-", "-") allIndex = getOpIndex(calcQuery, operations) if (calcQuery?.contains(op)!!) { val indexOp = calcQuery.indexOf(op) val indexIndexOp = allIndex.indexOf(indexOp) val rightIndex = if (indexIndexOp == allIndex.lastIndex) calcQuery.lastIndex else allIndex[indexIndexOp + 1] val leftIndex = if (indexIndexOp == 0) 0 else allIndex[indexIndexOp - 1] val rightNum = calcQuery.slice(if (rightIndex == calcQuery.lastIndex) indexOp + 1..rightIndex else indexOp + 1 until rightIndex) val leftNum = calcQuery.slice(if (leftIndex == 0) leftIndex until indexOp else leftIndex + 1 until indexOp) val result = basic(leftNum, rightNum, op) calcQuery = (if (leftIndex != 0) calcQuery.substring( 0, leftIndex + 1 ) else "") + result.toString() + (if(rightIndex != calcQuery.lastIndex) calcQuery.substring( rightIndex..calcQuery.lastIndex ) else "") } } } return calcQuery?.toDouble() } fun getAllIndex(query: String?, char: Char, replacement:String="%"):List<Int> { var myQuery = query var indexes:List<Int> = listOf() while (char in myQuery!!) { val indexFinded = myQuery.indexOf(char) indexes = indexes.plus(indexFinded) myQuery = myQuery.substring(0 until indexFinded) + replacement + myQuery.substring(indexFinded+1..myQuery.lastIndex) } return indexes } fun getBrackets(query: String?): List<Int> { val allEndIndex = getAllIndex(query, ')') val allStartIndex = getAllIndex(query, '(') val firstIndex = allStartIndex[0] for (endIndex in allEndIndex) { val inBrac = query?.substring(firstIndex+1 until endIndex) val inBracStart = getAllIndex(inBrac, '(') val inBracEnd = getAllIndex(inBrac, ')') if (inBracStart.size == inBracEnd.size){ return listOf(firstIndex, endIndex) } } return listOf(-1, -1) } fun evaluate(query:String?):Double? { var calcQuery = query var index = 0; // Check if brackets are present while (calcQuery?.contains('(')!! && index < 200){ val startBrackets = getBrackets(calcQuery)[0] val endBrackets = getBrackets(calcQuery)[1] val inBrackets = calcQuery.slice(startBrackets+1 until endBrackets) if ('(' in inBrackets && ')' in inBrackets){ val inBracValue = evaluate(inBrackets) calcQuery = calcQuery.substring(0, startBrackets) + inBracValue.toString() + (if(endBrackets == calcQuery.lastIndex) "" else calcQuery.substring(endBrackets+1..calcQuery.lastIndex)) } else { val inBracValue = parseSimple(inBrackets) calcQuery = calcQuery.substring(0, startBrackets) + inBracValue.toString() + (if(endBrackets == calcQuery.lastIndex) "" else calcQuery.substring(endBrackets+1..calcQuery.lastIndex)) } index++ } return parseSimple(calcQuery) } fun main() { print("Enter the equation: ") val equation = readLine() println(evaluate(equation)) }
A continuación se muestra el error devuelto.
Exception in thread "main" java.lang.NumberFormatException: empty String at jdk.internal.math.FloatingDecimal.readJavaFormatString (:-1) at jdk.internal.math.FloatingDecimal.parseDouble (:-1) at java.lang.Double.parseDouble (:-1)
Alternativamente, si alguien pudiera sugerirme un método diferente para resolver expresiones aritméticas en una aplicación de Android Kotlin que también ayudaría.
Intenté esto pero no funcionó.
Gracias de antemano.