Convertir la notation infixe en suffixe

Ce que sont la notation infixe et la notation postfixĂ©e peuvent ĂȘtre trouvĂ©s si vous lisez attentivement sur Wikipedia. Il y a aussi un article sur HabrĂ©.

Dans cet article, je vais montrer un algorithme simple et clair pour convertir les entrées infixes en postfixes. J'implémente cet algorithme dans le langage Kotlin, bien que l'algorithme soit adapté à n'importe quel langage de programmation.

Allez-y.

Pour une meilleure compréhension et mémorisation, nous utiliserons les abréviations:

  1. STACK - une pile est un type de donnĂ©es, qui est une liste d'Ă©lĂ©ments organisĂ©s selon le principe LIFO (le dernier est entrĂ©, le premier est sorti). Étude plus dĂ©taillĂ©e ici.
  2. QUEUE - une file d'attente est un type de donnĂ©es, qui est une liste d'Ă©lĂ©ments organisĂ©s selon le principe FIFO (premier arrivĂ©, premier sorti). Étude plus dĂ©taillĂ©e ici.
  3. PUSH - push, lorsque vous poussez, un nouvel élément est ajouté en haut de la pile, c'est-à-dire que l'élément en cours devient le haut de la pile (le dernier élément). Vous pouvez étudier en détail ici
  4. POP - dĂ©charge un Ă©lĂ©ment qui est le haut de la pile. Le haut est le dernier Ă©lĂ©ment de la pile. Plus de dĂ©tails peuvent ĂȘtre trouvĂ©s ici .
  5. TOP - le haut de la pile, c'est-à-dire son dernier élément

L'algorithme de conversion d'infixe en expression postfixée
.

  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-+.

Algorithme pour obtenir un résultat à partir d'une expression postfixée
.

  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

Par exemple, nous implémentons dans le langage Kotlin
: 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

C'est tout, tout est assez simple et clair.

All Articles