美文网首页
字符串四则运算 - 带括弧

字符串四则运算 - 带括弧

作者: 熊er | 来源:发表于2021-01-03 16:17 被阅读0次
import java.math.RoundingMode
import java.text.DecimalFormat

object Arithmometer {

    const val REGEX_VALID = "^[-+×÷*/()\\d.]*$" // 有效式子
    const val REGEX_NUM = "(?<!(\\d|\\)))-?(\\d+\\.?\\d*|\\.\\d+)" // 数字 - 前方不是数字或右括弧:负号(非减号) 数字[.数字] 或者 .数字
    const val REGEX_SINGLE = "($REGEX_NUM)([-+×÷*/])($REGEX_NUM)" // 单运算符式子
    const val REGEX_ADD_SUB = "($REGEX_NUM)([-+])($REGEX_NUM)" // 单运算符式子 - 加减
    const val REGEX_MUL_DIV = "($REGEX_NUM)([×÷*/])($REGEX_NUM)" // 单运算符式子 - 乘除
    const val REGEX_BRACKET = "\\([-+×÷*/\\d.]*\\)" // 括号式子
    const val REGEX_DOUBLE_MINUS = "(?<!(\\d|\\)))--" // 负负(得正)

    @Throws(IllegalStateException::class)
    fun compute(formula: String): String {
        return "\\s".toRegex().replace(formula, "").also {
            if (!REGEX_VALID.toRegex().matches(it)) error("syntax error")
        }.run {
            val cl = count { it == '(' }
            val cr = count { it == ')' }
            if (cl > cr) {
                (0 until cl - cr).joinToString("") { ")" }.let { "$this$it" }
            } else if (cr > cl) {
                if (takeLast(cr - cl).any { it == ')' }) {
                    dropLast(cr - cl)
                } else error("syntax error")
            } else this
        }.analyze()
    }

    private fun String.analyze(): String {
        var str = this.also { println(">$it") }

        // 括号优先
        var pattern = REGEX_BRACKET.toPattern()
        var matcher = pattern.matcher(str)
        while (matcher.find()) {
            str = str.replaceRange(matcher.start() until matcher.end(),
                    matcher.group().run { substring(1..length - 2) }.analyze()).also { println("=$it") }
            matcher = pattern.matcher(str)
        }

        // 负负得正
        if ("--" in str) {
            str = REGEX_DOUBLE_MINUS.toRegex().replace(str, "").also { println("=$it") }
        }

        // 先×÷再+-
        for (regexOp in arrayOf(REGEX_MUL_DIV, REGEX_ADD_SUB)) {
            pattern = regexOp.toPattern()
            matcher = pattern.matcher(str)
            while (matcher.find()) {
                val sub = matcher.group()
                str = str.replaceRange(matcher.start() until matcher.end(), sub.operate()).also { println("=$it") }
                matcher = pattern.matcher(str)
            }
        }

        return str
    }

    private fun String.operate(): String {
        return REGEX_SINGLE.toRegex()
                .replace(this, "$1`$4`$5")
                .split('`')
                .takeIf { it.size == 3 }
                ?.let { Triple(it[0].toBigDecimal(), it[1][0], it[2].toBigDecimal()) }
                ?.run {
                    when (second) {
                        '+' -> first.add(third).toString()
                        '-' -> first.subtract(third).toString()
                        '×', '*' -> first.multiply(third).toString()
                        '÷', '/' -> first.divide(third, 10, RoundingMode.HALF_UP)
                                .let { DecimalFormat("##0.##########").format(it) }
                        else -> error("syntax error")
                    }/*.also { println(">$formula=$it") }*/
                } ?: error(this)
    }

}

相关文章

  • 字符串四则运算 - 带括弧

  • 字符串中是否括弧是成对合法出现

    需求: 有一串字符串,里面包含若干个括弧,如何判断这些括弧是以成对出现的 (),且是合法的括弧 (),括弧支持嵌套...

  • 03.Perl -- 数据运算

    运算符 四则运算:+ - * / 字符串的四则运算在perl的规则中,如果一个字符串进行四则也能算,perl判断第...

  • PHP json返回大括弧和中括弧,json返回**{}**和

    PHP json返回大括弧和中括弧,json返回{}和[] 有时候,前端要求返回 大括弧和中括弧 前端要求返回{...

  • Python中的print 命令的用法

    Python编程中print的用法是输入print(),括弧中可以是数字、变量、字符串、列表、元组合字典。具体示例...

  • 随笔

    生命其實就是一個過程,不是一個結果。 生命是一個括弧。左邊括弧是出生,右邊括弧是死亡,我們要做的事情就是填括弧,要...

  • 双括弧

    双括弧 如果大洪水 又一次来了 并且没时间 造一艘 诺亚方舟 只有一个 双括弧 可以度过这场灾难 双括弧里...

  • 括弧子部

    本文参加‘青春’大赛,本人保证本文为本人原创,如有问题则与主办方无关,自愿放弃评优评奖资格。 深圳北理莫斯科大学 ...

  • js 各种基础类型的转换(下)隐式转换

    前言 在进行比较运算,或者进行四则运算时,常常会触发JS中的隐式转换机制。 非字符串到字符串的类型转换 加号运算符...

  • 括弧匹配检验

    括弧匹配检验 运行时限: 10000 ms 单次运行时限: 10000 ms 内存限制: 32 MB总提交...

网友评论

      本文标题:字符串四则运算 - 带括弧

      本文链接:https://www.haomeiwen.com/subject/rtauoktx.html