Проблема со считыванием и обработкой строки Kotlin



import android.annotation.SuppressLint
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import kotlin.math.pow
import kotlin.math.sqrt

class MainActivity : AppCompatActivity() {
    private lateinit var textView: TextView
    private var str = ""

    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        textView = findViewById(R.id.textView)

        val buttons = mapOf(
            R.id.button_0 to '0',
            R.id.button_1 to '1',
            R.id.button_2 to '2',
            R.id.button_3 to '3',
            R.id.button_4 to '4',
            R.id.button_5 to '5',
            R.id.button_6 to '6',
            R.id.button_7 to '7',
            R.id.button_8 to '8',
            R.id.button_9 to '9',
            R.id.dot to '.',
            R.id.plus to '+',
            R.id.minus to '-',
            R.id.multiplication to '*',
            R.id.division to '/',
            R.id.delete to 'd',
            R.id.sqrt to 's',
            R.id.factorial to '!',
            R.id.pow to '^'
        )

        buttons.forEach { (id, char) ->
            findViewById<Button>(id).setOnClickListener {
                handleButtonClick(char)
            }
        }

        findViewById<Button>(R.id.equal).setOnClickListener {
            calculateResult()
        }
    }

    private fun handleButtonClick(char: Char) {
        when (char) {
            '.' -> {
                if (str.isNotEmpty() && !str.endsWith('.') && !isLastCharOperator()) {
                    str += char
                }
            }
            '0' -> {
                if (str != "0") {
                    str += char
                }
            }
            'd' -> {
                if (str.isNotEmpty()) {
                    str = str.dropLast(1)
                }
            }
            else -> str += char
        }
        textView.text = str
    }

    private fun isLastCharOperator(): Boolean {
        return str.isNotEmpty() && str.last() in listOf('+', '-', '*', '/', '^', 's', '!')
    }

    private fun calculateFactorial(number: Int): Double {
        if (number < 0) throw IllegalArgumentException("Factorial is not defined for negative numbers")
        return (1..number).fold(1L.toDouble()) { acc, i -> acc * i }
    }

    private fun calculateResult() {
        try {
            val result = eval(str)
            str = result.toString()
            textView.text = str
        } catch (e: Exception) {
            textView.text = "Error"
            str = ""
        }
    }

    private fun eval(expression: String): Double {
        val parts = expression.split(Regex("(?<=[-+*/!^s])|(?=[-+*/!^s])"))

        // Проверка на пустое выражение
        if (parts.isEmpty()) return 0.0

        var total = parts[0].toDouble()

        for (i in 1 until parts.size step 2) {
            val operator = parts[i]
            val nextValue = if (i + 1 < parts.size) parts[i + 1].toDouble() else 0.0

            when (operator) {
                "+" -> total += nextValue
                "-" -> total -= nextValue
                "*" -> total *= nextValue
                "/" -> {
                    if (nextValue == 0.0) throw ArithmeticException("Division by zero")
                    total /= nextValue
                }
                "^" -> total = total.pow(nextValue)
                "s" -> total = sqrt(total) // Square root operation
                "!" -> total = calculateFactorial(total.toInt()) // Factorial operation
            }
        }

        return total
    }
}

Вот основной код программы(калькулятора), проблема в том, что при вводе 16s он выводит error, но при вводе "16s0" он все решает благополучно. Можете изменить код так, чтобы он мог все операции делать верно.


Ответы (0 шт):