Оценка строки в kotlin

Я написал код в kotlin для оценки заданной строки из Divison для вычитания, он работает, но дает неправильный ответ, например, я получил строку x в первой строке с ответом -215,96666, тогда как ответ из кода -237,366666 idk где ошибка. я видел больше людей, использующих стек для этого, но я хотел сделать это для оценки строки

var x : String = "5+4-10x20-40/30x20+34/20"

fun div(x: String): String {
    val lis1 = x.split("-").toMutableList()
    for (ele1 in lis1) {
        if ("/" in ele1) {
            val pos1 = lis1.indexOf(ele1)
            val lis2 = ele1.split("+").toMutableList()
            for (ele2 in lis2) {
                if ("/" in ele2) {
                    val pos3 = lis2.indexOf(ele2)
                    val lis3 = ele2.split("x").toMutableList()
                    for (ele3 in lis3) {
                        if ("/" in ele3) {
                            val pos4 = lis3.indexOf(ele3)
                            val lis4 = ele3.split("/")
                            val div = (lis4[0].toDouble() / lis4[1].toDouble()).toString()
                            lis3[pos4] = div
                        }
                    }
                    lis2[pos3] = lis3.joinToString("x")
                }
            }
            lis1[pos1] = lis2.joinToString("+")

        }
    }
    return (lis1.joinToString("-"))
}

fun mul(x : String) : String{
    val lis1 = x.split("-").toMutableList()
    for (ele1 in lis1) {
        if ("x" in ele1){
            val pos1 = lis1.indexOf(ele1)
            val lis2 = ele1.split("+").toMutableList()
            for(ele2 in lis2){
                if ("x" in ele2){
                    val pos2 = lis2.indexOf(ele2)
                    val lis3 = ele2.split("x")
                    val mul = (lis3[0].toDouble() * lis3[1].toDouble()).toString()
                    lis2[pos2] = mul
                }
            }
            lis1[pos1] = lis2.joinToString("+")
        }
    }
    return (lis1.joinToString("-"))
}

fun add(x : String): String {
    val lis1 = x.split("-").toMutableList()
    for(ele1 in lis1){
        if ("+" in ele1){
            val pos1 = lis1.indexOf(ele1)
            val lis2 = ele1.split("+")
            val add = (lis2[0].toDouble() + lis2[1].toDouble()).toString()
            lis1[pos1] = add
        }
    }
    return (lis1.joinToString("-"))
}

fun sub(x : String) : String{
    val lis1 = x.split("-").toMutableList()
    var sub = 0.0
    for(ele1 in lis1){
        sub -= ele1.toDouble()
    }
    return (sub.toString())
}

fun eval(x: String): String {
    val divanswer = div(x)
    val mulanswer = mul(divanswer)
    val addanswer = add(mulanswer)
    return sub(addanswer)
}

fun main(args: Array<String>){
    println(eval(x))
}




i wanted the answer as -215.96666 but the answer given by code is -237.366666

Я не думаю, что это должно быть сделано таким образом. Вам следует подумать о написании синтаксического анализатора для вычисления арифметических выражений.

lukas.j 14.02.2023 18:03

@ lukas.j Полный синтаксический анализатор - правильный путь, но я очень ценю креативность ОП. Они сами ищут способ, как это сделать, с таким настроем узнают гораздо больше, чем авторы типичных вопросов: "Как написать калькулятор, помогите". Кроме того, я думаю, что этот подход в конечном итоге должен работать, однако было бы довольно сложно добавить поддержку скобок.

broot 14.02.2023 20:19

@broot Я согласен с вами по поводу творчества и процесса обучения. Но, с другой стороны, вычисление арифметических выражений было решено несколько десятилетий назад, и, возможно, это не то место, куда нужно вкладывать время. Вероятно, два наиболее важных решения — это, во-первых, то, что я бы назвал «рекурсией выражения-терма-фактора», и, во-вторых, преобразование входной строки в стек операторов и операндов, а затем инфикс в постфикс и оценка стека. больше смысла тратить время на разработку пользовательского кода на основе этих известных решений.Но я понимаю, что вы имеете в виду в отношении этого вопроса.

lukas.j 14.02.2023 20:46

@ lukas.j да, это похоже на неправильное место для вложения времени, но мне действительно нравится программировать, когда я решаю такие задачи, так что для меня это не похоже на трату времени, а просто заставляет меня заниматься тем, что мне нравится, я спросил мои друзья и на многих веб-сайтах, ответ был просто использовать стек или массив, чтобы сделать это, но если есть другой способ сделать это, но это беспорядок, я обязательно попробую...

Blaze_2508 15.02.2023 06:31
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как сделать компонент справочного центра с помощью TailwindCSS
Как сделать компонент справочного центра с помощью TailwindCSS
Справочный центр - это веб-сайт, где клиенты могут найти ответы на свои вопросы и решения своих проблем. Созданный для решения многих распространенных...
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
1
4
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В случае этого конкретного ввода есть две ошибки.

Первая ошибка связана с тем, что вы сначала обрабатываете +, а затем -, но в математике мы должны обрабатывать их вместе, слева направо. В результате ваш алгоритм обрабатывает это: 1-1+1 (правильный ответ: 1) как: 1-(1+1) (ответ: -1). В качестве альтернативы, я считаю, что обработка - сначала, а затем + должна работать правильно.

Вторая ошибка заключается в том, что в sub() вы начинаете с 0 и вычитаете даже первое число, но на самом деле первое число должно быть добавлено или использовано в качестве начального значения.

Я считаю, что после исправления этих двух ошибок он должен дать правильный ответ для этого конкретного ввода, но, вероятно, таких ошибок больше. Например, вы неправильно обрабатываете цепочки одного и того же оператора, вас интересует только первая пара, поэтому 1+1+1 становится 2 (а затем превращается в -2 из-за ранее упомянутой ошибки).

Общий совет: научитесь пользоваться отладчиком и анализируйте, как меняются ваши данные, пока код их обрабатывает. Даже если вы просто распечатаете свои промежуточные результаты: divanswer, mulanswer и addanswer, а затем пропустите их через Google для обработки, вы заметите, что где-то на шаге add() есть проблема. Затем промойте и повторяйте, пока все не будет работать правильно.

Спасибо, это была часть вычитания и сложения, которая вызвала проблемы, теперь я изменил и объединил ее в одну, теперь я получаю правильный ответ для строк, которые я использовал, теперь мне нужно заполнить только скобки, еще раз спасибо за это. !

Blaze_2508 15.02.2023 06:18

Спасибо @broot за то, что заметил это, проблема заключалась в части сложения и вычитания, теперь, когда я объединил их в один и получил правильные ответы для строк, которые я ввел, вот исправленный полный код.


var x : String = "5+4-10x20-40/30x20+34/20"

fun div(x: String): String {
    val lis1 = x.split("-").toMutableList()
    for (ele1 in lis1) {
        if ("/" in ele1) {
            val pos1 = lis1.indexOf(ele1)
            val lis2 = ele1.split("+").toMutableList()
            for (ele2 in lis2) {
                if ("/" in ele2) {
                    val pos3 = lis2.indexOf(ele2)
                    val lis3 = ele2.split("x").toMutableList()
                    for (ele3 in lis3) {
                        if ("/" in ele3) {
                            val pos4 = lis3.indexOf(ele3)
                            val lis4 = ele3.split("/")
                            val div = (lis4[0].toDouble() / lis4[1].toDouble()).toString()
                            lis3[pos4] = div
                        }
                    }
                    lis2[pos3] = lis3.joinToString("x")
                }
            }
            lis1[pos1] = lis2.joinToString("+")

        }
    }
    return (lis1.joinToString("-"))
}

fun mul(x : String) : String{
    val lis1 = x.split("-").toMutableList()
    for (ele1 in lis1) {
        if ("x" in ele1){
            val pos1 = lis1.indexOf(ele1)
            val lis2 = ele1.split("+").toMutableList()
            for(ele2 in lis2){
                if ("x" in ele2){
                    val pos2 = lis2.indexOf(ele2)
                    val lis3 = ele2.split("x")
                    val mul = (lis3[0].toDouble() * lis3[1].toDouble()).toString()
                    lis2[pos2] = mul
                }
            }
            lis1[pos1] = lis2.joinToString("+")
        }
    }
    return (lis1.joinToString("-"))
}

fun final(x: String): Double {
    val substr = StringBuffer()
    var answer = 0.0
    var opr = '+'
    for(ele in x.indices){
        var current = x[ele]
        if (current in '0'..'9' || current == '.'){
            substr.append(current)
        }
        if (current == '-' || current == '+'){
            var operand = substr.toString().toDouble()
            substr.setLength(0)
            when (opr){
                '+' -> answer += operand
                '-' -> answer -= operand
            }
            opr = current
        }
    }
    val num = substr.toString().toDouble()
    when(opr){
        '+' -> answer += num
        '-' -> answer -= num
    }
    return answer
}


fun eval(x: String): Double {
    val divanswer = div(x)
    return final(mul(divanswer))
}

fun main(args: Array<String>){
    println(eval(x))
}

Другие вопросы по теме