Convert infix notation to postfix

What is infix notation and postfix notation can be found if you carefully read on Wikipedia. There is also an article on Habré.

In this article I will show a simple and clear algorithm for converting infix entries to postfix ones. I implement this algorithm in the Kotlin language, although the algorithm is suitable for any programming language.

Well, go ahead.

For a better understanding and memorization, we will use the abbreviations:

  1. STACK - a stack is a data type, which is a list of elements organized according to the LIFO principle (the last to come - the first to come out). More detailed study here.
  2. QUEUE - a queue is a data type, which is a list of elements organized according to the FIFO principle (first come, first come out). More detailed study here.
  3. PUSH - push, when pushing, a new element is added to the top of the stack, that is, the current element becomes the top of the stack (the last element). You can study in detail here
  4. POP - unloads an element that is the top of the stack. The top is the last item on the stack. More details can be found here .
  5. TOP - the top of the stack, that is, its last element

The conversion algorithm from infix to postfix expression
.

  1. , (QUEUE).
  2. (+, -, *, /) :

    • (STACK) (TOP), (PUSH) (STACK).
    • (TOP), (PUSH) (STACK).
    • , (TOP), POP (QUEUE), (TOP), (PUSH) (STACK).

  3. , (PUSH) (STACK).
  4. , (POP) (QUEUE), . (STACK).
  5. (POP) (QUEUE)

: 5*6+(2-9)
.
STACK = empty
QUEUE = empty

  • 5. .
    STACK = empty
    QUEUE = 5
  • *. .
    STACK = *
    QUEUE = 5
  • 6. .
    STACK = *
    QUEUE = 5, 6
  • +. , . , . .
    STACK = +
    QUEUE = 5, 6, *
  • (. .
    STACK = +, (
    QUEUE = 5, 6, *
  • 2. .
    STACK = +, (
    QUEUE = 5, 6, *, 2
  • . , "", "(". .
    STACK = +, (, —
    QUEUE = 5, 6, *, 2
  • 9 . .
    STACK = +, (, —
    QUEUE = 5, 6, *, 2, 9
  • ) . , . .
    STACK = +
    QUEUE = 5, 6, *, 2, 9, —
  • , .
    STACK = empty
    QUEUE = 5, 6, *, 2, 9, -, +

56*29-+.

Algorithm for obtaining a result from a postfix expression
.

  1. , (PUSH) (STACK)
  2. (*-/+), (POP) (STACK) . (PUSH) (STACK).
  3. , (TOP) (STACK) .

: 56*29-+.

.

STACK = empty

  • 5. .
    STACK = 5
  • 6. .
    STACK = 5, 6
  • * . (5 * 6), , .
    STACK = 30
  • 2 . .
    STACK = 30, 2
  • 9 . .
    STACK = 30, 2, 9
  • . (2 — 9), , .
    STACK = 30, -7
  • + . (-7 + 30), , .
    STACK = 23

:

: 5*6+(2-9) = 23

: 56*29-+ = 23

For example, we implement in the Kotlin language
: 5*8*(2+9)+(7*5+8-9*(5*5)+5) = 263

  1. , expressionList: mutableListOf<String>()
    private var stack = mutableListOf<String>()
    private var queue = mutableListOf<String>()
    private var expressionList = mutableListOf<String>()
    
    fun main() {
        parseExpression()
    }
    
    fun parseExpression() {
        "5*8*(2+9)+(7-5+8-9*(5*5)+5)".forEach {
            expressionList.add(it.toString())
        }
        print(" : ")
        expressionList.forEach {
            print(it)
        }
        println()
    }
    


  2. private fun getPostFixEx() {
        //  expressionList
        expressionList.forEach {
            when {
                //      PUSH
                it == "(" -> push(it)
    
                //      POP
                it == ")" -> {
                    if (expressionList.contains("(")) {
                        pop()
                    }
                }
    
                //   ,    
                Regex("[\\d]").containsMatchIn(it) -> addQueue(it)
    
                //   +  -
                Regex("[+-]").containsMatchIn(it) ->
                    /* ,         ,
                    *   PUSH */
                    if (stack.isEmpty() || stack.last() == "(") push(it)
                    /* ,       
                    * ,   POP,  PUSH */
                    else if (stack.last().contains(Regex("[/*]"))) {
                        pop()
                        push(it)
                    }
                    //    PUSH
                    else {
                        addQueue(stack.last())
                        stack[stack.lastIndex] = it
                    }
    
                //   *  /
                Regex("[*/]").containsMatchIn(it) -> {
                    /* ,         ,
                    *   POP */
                    if (stack.isNotEmpty() && (stack.last() == "*" || stack.last() == "/")) {
                        pop()
                    }
                    //   PUSH
                    push(it)
                }
            }
        }
        //     ,       
        if (stack.isNotEmpty()) {
            for (i in stack.lastIndex downTo 0) {
                if (stack[i] != "(") {
                    addQueue(stack[i])
                }
            }
        }
        print(" : ")
        queue.forEach {
                print(it)
        }
        println()
    
    }
    
    private fun pop() {
        //         ,     
        Loop@ for (i in stack.lastIndex downTo 0) {
            if (stack[i] == "(") {
                stack[i] = " "
                break@Loop
            }
            addQueue(stack[i])
            stack[i] = " "
        }
        stack.removeIf { it == " " }
    }
    
    private fun addQueue(item: String) {
        queue.add(item)
    }
    
    private fun push(item: String) {
        stack.add(item)
    }
    


  3. private fun calcPostFix() {
        //   
        val stack = mutableListOf<Int>()
        //    
        for (item in queue) {
            when {
                //    - ,    
                Regex("[\\d]").containsMatchIn(item) -> {
                    stack.add(item.toInt())
                }
                /*    + ,    
                    */
                item == "+" -> {
                    stack[stack.lastIndex - 1] = stack[stack.lastIndex - 1] + stack.last()
                    stack.removeAt(stack.lastIndex)
                }
                /*    * ,    
                    */
                item == "*" -> {
                    stack[stack.lastIndex - 1] = stack[stack.lastIndex - 1] * stack.last()
                    stack.removeAt(stack.lastIndex)
                }
                /*    / ,    
                    */
                item == "/" -> {
                    stack[stack.lastIndex - 1] = stack[stack.lastIndex - 1] / stack.last()
                    stack.removeAt(stack.lastIndex)
                }
                /*    -,    
                     */
                item == "-" -> {
                    stack[stack.lastIndex - 1] = stack[stack.lastIndex - 1] - stack.last()
                    stack.removeAt(stack.lastIndex)
                }
            }
        }
    
        //  -  ,    
        println(": ${stack.first()}")
    }
    



:

: 5*8*(2+9)+(7-5+8-9*(5*5)+5)

: 58*29+*75-8+955**-5++

: 230

That's all, everything is quite simple and clear.

All Articles