当前位置: 首页 > 知识库问答 >
问题:

在负数情况下如何执行操作?

松德曜
2023-03-14

我想为android构建一个计算器应用程序,为此我需要一个解析器来转换要求解的字符串表达式。现在Java和Kotlin不支持eval函数,仅仅为了一个操作而导入javascript引擎可能会让我面临各种漏洞。所以我做了自己的计算器解析器。现在它工作得很好,除了crash中的负数外,所有算术运算都工作得很好。我确实知道问题是什么,因为我使用数学符号分隔字符串,但我不能在负值中执行任何操作。

输入:-5预期:0输出:异常(numberFormatException)

这是kotlin类:

    class CalculatorParser(private var expression: String) {

    init {
        if (expression.isEmpty() || expression == "0") {
            expression = "0+0"
        } else if (expression.split("+", "-", "*", "/", "^").size == 1) {
            expression = "$expression+0"
        }
    }

    private val splitStr = expression.split("+", "-", "*", "/", "^").toMutableList()
    private val a = splitStr[0].toFloat()
    private val b = splitStr[1].toFloat()
    private val operator = getDelimiter(expression)

    private fun getDelimiter(str: String): String {
        return if (str.contains("+")) {
            "+"
        } else if (str.contains("-")) {
            "-"
        } else if (str.contains("*")) {
            "*"
        } else if (str.contains("^")) {
            "^"
        } else {
            "/"
        }
    }

    private fun calculate(): Float {
        return when (operator) {
            "+" -> a + b
            "-" -> a - b
            "*" -> a * b
            "/" -> a / b
            "^" -> pow(a.toInt(), b.toInt()).toFloat()
            else -> {
                return 0f
            }
        }
    }

    fun eval(result: Float = calculate()): String {
        var final = ""
        if (result.toString().contains(".")) {
            val splitResult = result.toString().split(".")
            final = if (splitResult[1].toInt() > 0) {
                result.toString()
            } else {
                result.toInt().toString()
            }
        }
        println(splitStr) // This print statement is only for testing the split array in console to be deleted in production code.
        return final
    }

    private fun pow(base: Int, power: Int): Int {
        var result = base
        var i = 1
        while (i < power) {
            result *= base
            i++
        }
        return result
    }
}

共有1个答案

苏德容
2023-03-14
 private val splitStr = expression.split("+", "-", "*", "/", "^").toMutableList()
 private val a = splitStr[0].toFloat()

由于这些行的问题,当您拆分为“-”并且您编写-5 5时,它正在拆分为-并且第一个元素为空(“”),根据本网站,当您尝试解析空字符串以浮动时,这会导致数字格式异常。为了解决这个问题,也许您可以检查第一个元素是否为“-”,您可以将该表达式转换为“5-5”,这将为您提供结果。

关键在这里。您不应该使用“”-”...作为表达式中的第一个元素。因为您不能转换为空字符串(“”)以浮动。我希望我的解释很清楚。

 类似资料:
  • 我正在使用一个房间数据库来运行一些繁重的数据库操作。我没有使用LiveData进行此操作,因为我只将结果用于计算。如果在我的主要片段中 我得到一个如果忽略数据库查询,就不会得到这些工作。 这里的一些答案(比如这个或那个)似乎建议在IO线程上运行查询,比如 注意:Room使用自己的dispatcher在后台线程上运行查询。您的代码不应该使用withContext(Dispatchers.io)来调用

  • 问题内容: 我有以下代码: 在发生某些事件之后,我应该停止在的方法中声明的操作,该方法实现。 我怎样才能做到这一点?我无法关闭执行器,只能撤消我的定期任务。我可以用吗?如果可以的话,请告诉我它将如何工作。 问题答案: 使用。该是你的任务的处理。您需要取消此任务,它将不再执行。 实际上,是签名,并将其与参数一起使用将导致当前正在运行的执行线程被调用中断。如果线程在阻塞的可中断调用(例如)中等待,则会

  • 我有一个动作执行,其中一个if/fe是如果用户按“A”键,它会将文本设置为不同的内容。程序不是在按“A”后设置文本,而是跳过设置文本并向下移动到下面的if语句。我的问题是,如何让我的程序在我的if语句之前设置文本?我的代码在下面,谢谢!

  • 我有一个返回字符串的函数。 返回的结果可以是回答,也可以是回答

  • 问题内容: 我想在Centos7上使用shell脚本自动生成一对ssh密钥,我已经尝试过 所有这些命令都不起作用,仅输入一个“ enter”,然后在“ Enter passphrase(空无密码)为空”时停止shell脚本,我只想知道如何在shell中连续模拟多个“ enter”。 非常感谢任何人的帮助! 问题答案: 只需 使用一个空白通 使用标志: 要覆盖密钥文件 (在此示例中): 从 手册 页

  • 我正在编写一个java程序,其中我不想对数组列表元素使用任何循环。下面的Sure程序将在不使用任何循环的情况下将输出从0打印到n,因为ArrayList从AbstractCollection继承了一个带有循环的toString()方法。 现在,如果我使用这个程序,这将给我大约O(n*m)解,这是我不想要的。是否有任何方法可以访问数组列表中的所有元素而不使用任何循环?