3/24/15 Uso dello stack nella valutazione delle espressioni aritmetiche Corso: Strutture Dati Docente: Annalisa De Bonis Valutare le espressioni aritmetiche l Quando si valuta un’espressione aritmetica bisogna tener conto dell’ordine di precedenza e dell’associatività degli operatori l l Qui consideriamo espressioni con operatori aritmetici associativi a sinistra Idea: l Due stack: l valStack per i valori l opStack per gli operatori § Si fa il push di ogni operatore ma solo dopo aver estratto e applicato tutti gli operatori con precedenza maggiore o uguale 1 3/24/15 Algoritmo EvalExp() Input: una stringa che rappresenta un’espressione aritmetica Output: il valore dell’espressione while c’è un altro carattere c da scandire if c è un numero then valStack.push(c) else while( opStack non è vuoto ∧ precedenza( c ) ≤ precedenza(opStack.top())) x ← valStk.pop(); //fino a che al top dello stack ci sono operatori con y ← valStk.pop(); //priorità maggiore rispetto a c, si estrae il pop op ← opStk.pop(); // di opStack e si applica l’operatore estratto ai valStack.push( y op x ); // due operandi in cima a valStack opStack.push( c ) while( opStack non è vuoto ) //alla fine si applicano gli operatori rimasti in opStack x ← valStk.pop(); //agli operandi rimasti in vaStack y ← valStk.pop(); op ← opStk.pop(); valStack.push( y op x ); return valStack.top(); Esempio 3 + 4 * 6 - 8 6 4 4 3 3 3 + 4 3 + 3 8 * + 27 - 24 * + 3 19 + 27 - restituisce 19 2 3/24/15 Esempio 9 + 4 - 6 - 2 9 9 9 2 6 4 13 + + 13 5 - - 7 7 - - restituisce 5 Esercizio 1 l Se l’espressione è in notazione postfissa è possibile valutarla usando un unico stack? l Esempi di espressioni aritmetiche in notazione postfissa l 1 2 + 5 * corrisponde a ( 1 + 2 ) * 5 l 1 2 5 * + corrisponde a 1 + 2 * 5 3 3/24/15 01/03/12 Soluzione esercizio 1 l Soluzione esercizio 1 Usiamo uno stack per gli operandi l l Usiamo per gli un operandi Ogni voltauno chestack incontriamo operando facciamo il ! Ogni volta che incontriamo un operando push dell’operando facciamo il push dell’operando Ogni volta che incontriamo un operatore ! Ogni volta che incontriamo un operatore 1. preleviamo (con 2 operazioni di pop) 2 1. preleviamo (con 2 operazioni di pop) 2 operandi operandi dallo stack dallo stack ! 2. Applichiamo l’operatore ai due operandi e facciamo il push 2. Applichiamo l’operatore ai due operandi e facciamo il del risultato nello stacknello stack push del risultato Esempio: 6 2 * 4 + 2 6 Strutture Dati 2011-2012 A. De Bonis 6 / 6 2 6 + 12 4 12 16 2 16 2 16 8 16 2 Esercizio 2 Esercizio 2 E` possibile utilizzare un unico stack per trasformareutilizzare un’espressione infissa in per E` possibile un unico stack postfissa? ! l trasformare un’espressione infissa in postfissa? Strutture Dati 2011-2012 A. De Bonis 4 4 3/24/15 Soluzione esercizio 2 l Gli operandi compaiono nello stesso ordine in cui comparivano nella postfissa l l Di conseguenza non appena si incontra un operando lo aggiungiamo alla stringa output Gli operatori invece cambiano posizione in quanto 1. 2. devono seguire gli operandi possono cambiare d’ordine a causa delle regole di priorità e delle parentesi Soluzione esercizio 2 l Idea: Usiamo uno stack per gestire i raggrupamenti nelle parentesi e le precedenze degli operatori. l Quando incontriamo ‘(‘ facciamo il push della parentesi nello stack. l Quando incontriamo ‘)’ facciamo il pop di tutti gli operatori fino a che al top dello stack non compare ‘(‘. (Facciamo il pop anche di ‘(‘ ). l Man mano che estraiamo gli operatori dallo stack, li inseriamo nella stringa output. l Quando incontriamo uno degli operatori +, -, /, *, lo inseriamo nello stack dopo aver fatto il pop di tutti gli operatori con priorità maggiore o uguale. l Man mano che estraiamo gli operatori dallo stack, li inseriamo nella stringa output. 5 01/03/12 01/03/12 3/24/15 Soluzione Soluzione esercizio esercizio 2: 2: lo lo pseudocodice Soluzione esercizio 2 pseudocodice Input: stringa che rappresenta un’espressione aritmetica in notazione infissa Input: stringa che rappresenta un’espressione aritmetica in notazione infissa Output: stringa che rappresenta l’espressione input in notazione postfissa Output: stringa che rappresenta l’espressione input in notazione postfissa /* Lo pseudocodice assume che l’espressione sia ben formata*/ /* Lo pseudocodice assume che l’espressione sia ben formata*/ Crea una stringa vuota Postfix; Crea una stringa vuota Postfix; Crea Creauno unostack stackopStack; opStack; while (c’è un while (c’è unaltro altrocarattere carattereccda dascandire){ scandire){ ififc cèèun operando then aggiungi un operando then aggiungiccalla alla fine fine della della stringa stringa Postfix; Postfix; else if c== ‘(‘ then opStack.push(c); else if c== ‘(‘ then opStack.push(c); else elseififcc== ==‘)’‘)’then then{ { while ( opStack while ( opStacknon nonèèvuoto vuotoAND AND opStack.top() opStack.top() != != ‘(‘ ‘(‘ )) { {aggiungi aggiungiopStack.top() opStack.top()alla allafine finedella della stringa stringa Postifix Postifix ;; opStack.pop(); opStack.pop(); }} opStack.pop(); //faccio il pop di ‘(‘ opStack.pop(); //faccio il pop di ‘(‘ } }//fine //finecaso casocc== ==‘)’‘)’ Continua # Strutture StruttureDati Dati 2011-2012 2011-2012 A.A.De DeBonis Bonis Soluzione esercizio esercizio 2: lo Soluzione Soluzione esercizio 2 pseudocodice pseudocodice else{ {////ccèèuno unodegli degli operatori operatori +, +, -,-, /,/, ** else /*estraiamodallo dallostack stackeeaggiungiamo aggiungiamo alla alla stringa stringa /*estraiamo tutti gli operatori con precedenza maggiore uguale di di c*/ c*/ tutti gli operatori con precedenza maggiore oo uguale while(opStack (opStacknon nonèèvuoto vuotoAND AND opStack.top() opStack.top() != != ‘(‘ ‘(‘ AND AND while prec(opStack.top()) >= prec(c) ) { prec(opStack.top()) >= prec(c) ) { aggiungi opStack.top() alla fine di Postfix; opStack.pop(); aggiungi opStack.top() alla fine di Postfix; opStack.pop(); } } opStack.push(c ); opStack.push(c ); } // fine else } // fine else } //fine del while esterno che serve a scandire la stringa input } //fine del while esterno che serve a scandire la stringa input while (opStack non è vuoto) //al termine svuoto lo stack while (opStack non è vuoto) //al termine svuoto lo stack {aggiungi opStack.top() alla fine di Postfix ; opStack.pop(); {aggiungi opStack.top() alla fine di Postfix ; opStack.pop(); } } Strutture Dati 2011-2012 A. De Bonis Strutture Dati 2011-2012 A. De Bonis 666
© Copyright 2024 Paperzz