Оценка строки в 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
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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))
}

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