Преобразование инфикса в постфикс в Kotlin: подробное руководство

Инфиксная и постфиксная нотации — два распространенных способа представления математических выражений. В то время как инфиксная нотация — это знакомая математическая нотация, которую мы используем в повседневной жизни (например, 2 + 3), постфиксная нотация, также известная как обратная польская нотация (RPN), представляет операторы после операндов (например, 2 3 +). В этой статье мы рассмотрим различные методы преобразования инфиксных выражений в постфиксные в Котлине. Итак, приступим!

Метод 1: использование стеков
Один из самых популярных подходов к преобразованию инфикса в постфикс — использование стека. Вот фрагмент кода, демонстрирующий реализацию:

fun infixToPostfix(expression: String): String {
    val output = StringBuilder()
    val stack = Stack<Char>()
    val precedence = mapOf('+' to 1, '-' to 1, '*' to 2, '/' to 2, '^' to 3)
    for (char in expression) {
        when {
            char.isLetterOrDigit() -> output.append(char)
            char == '(' -> stack.push(char)
            char == ')' -> {
                while (!stack.isEmpty() && stack.peek() != '(') {
                    output.append(stack.pop())
                }
                stack.pop() // Discard '('
            }
            else -> {
                while (!stack.isEmpty() && precedence[char]!! <= precedence[stack.peek()]!!) {
                    output.append(stack.pop())
                }
                stack.push(char)
            }
        }
    }
    while (!stack.isEmpty()) {
        if (stack.peek() == '(') throw IllegalArgumentException("Invalid expression")
        output.append(stack.pop())
    }
    return output.toString()
}

Метод 2: использование деревьев выражений
Другой подход к преобразованию инфикса в постфикс заключается в построении дерева выражений и последующем обходе его в постфиксном порядке. Вот реализация:

class Node(private val value: Char) {
    var left: Node? = null
    var right: Node? = null
}
fun infixToPostfix(expression: String): String {
    val stack = Stack<Node>()
    var root: Node? = null
    for (char in expression) {
        if (char.isLetterOrDigit()) {
            val node = Node(char)
            stack.push(node)
        } else {
            val right = stack.pop()
            val left = stack.pop()
            val node = Node(char)
            node.left = left
            node.right = right
            stack.push(node)
        }
    }
    root = stack.pop()
    val output = StringBuilder()
    traversePostorder(root, output)
    return output.toString()
}
fun traversePostorder(node: Node?, output: StringBuilder) {
    if (node != null) {
        traversePostorder(node.left, output)
        traversePostorder(node.right, output)
        output.append(node.value)
    }
}

Метод 3: алгоритм сортировочной станции
Алгоритм сортировочной станции — еще один популярный метод преобразования инфикса в постфикс. Вот фрагмент кода, демонстрирующий его реализацию:

fun infixToPostfix(expression: String): String {
    val output = StringBuilder()
    val stack = Stack<Char>()
    val precedence = mapOf('+' to 1, '-' to 1, '*' to 2, '/' to 2, '^' to 3)
    for (char in expression) {
        when {
            char.isLetterOrDigit() -> output.append(char)
            char == '(' -> stack.push(char)
            char == ')' -> {
                while (!stack.isEmpty() && stack.peek() != '(') {
                    output.append(stack.pop())
                }
                stack.pop() // Discard '('
            }
            else -> {
                while (!stack.isEmpty() && precedence[char]!! <= precedence[stack.peek()]!!) {
                    output.append(stack.pop())
                }
                stack.push(char)
            }
        }
    }
    while (!stack.isEmpty()) {
        output.append(stack.pop())
    }
    return output.toString()
}

В этой статье мы рассмотрели три различных метода преобразования инфиксных выражений в постфиксные в Kotlin. Мы реализовали алгоритмы с использованием стеков, деревьев выражений и алгоритма сортировочной станции. Каждый метод имеет свои преимущества и может быть более подходящим в зависимости от требований вашего проекта. По мере того, как вы познакомитесь с этими приемами, вы сможете без особых усилий обрабатывать сложные выражения. Приятного кодирования!