Supponiamo di voler scrivere un algoritmo che
riceva in ingresso una espressione aritmetica, e verifichi il corretto
bilanciamento delle parentesi.
Se le parentesi sono solo tonde, basta utilizzare una
variabile intera (un contatore).
Esercizio: Scrivere un algoritmo che risolva
il problema, restituendo true se l'espressione è
bilanciata, false altrimenti.
Esempi:
(((())())) -> true
((()())))(((()())) -> false
|
Se le parentesi possono essere graffe, quadre o tonde,
è facile convincersi che non bastano uno o più contantori,
ma occorre ricordare la sequenza delle parentesi aperte.
Esempi:
([({})[]]) -> true
([({)}[]]) -> false
Il seguente algoritmo risolve il problema usando una pila:
0. Sia data una stringa str in
input;
1. crea una pila vuota;
2. leggi il prossimo carattere c
di str:
2.1. se c non è
una parentesi, passa al carattere successivo;
2.2. se c è una parentesi
aperta, inseriscilo nella pila;
2.3. altrimenti (c è una
parentesi chiusa),
2.3.1 se la pila è vuota, restituisci
false;
2.3.2 altrimenti (la pila non è vuota),
estraine la cima (il carattere c')
2.3.2.1 se la parentesi aperta c'
e
quella chiusa c sono dello stesso tipo, passa al carattere
successivo
2.3.2.2 altrimenti restituisci false
3. quando sono finiti i caratteri,
3.1 se la pila è vuota, restituisci
true;
3.2 altrimenti restituisci
false.
|
stringa |
operazione |
stack (dopo operazione) |
esito |
([({})[]])
^
c
|
Stack<String> pila = new Stack<String>();
pila.push("(");
|
|
|
([({})[]])
^
c
|
pila.push("[");
|
|
|
([({})[]])
^
c
|
pila.push("(");
|
|
|
([({})[]])
^
c
|
pila.push("{");
|
|
|
([({})[]])
^
c
|
pila.empty() è false
c' = pila.pop(); ovvero c' = "{"
c match c' è true
|
|
|
([({})[]])
^
c
|
pila.empty() è false
c' = pila.pop(); ovvero c' = "("
c match c' è true
|
|
|
([({})[]])
^
c
|
pila.push("[")
|
|
|
([({})[]])
^
c
|
pila.empty() è false
c' = pila.pop(); ovvero c' = "["
c match c' è true
|
|
|
([({})[]])
^
c
|
pila.empty() è false
c' = pila.pop(); ovvero c' = "["
c match c' è true
|
|
|
([({})[]])
^
c
|
pila.empty() è false
c' = pila.pop(); ovvero c' = "("
c match c' è true
|
|
|
([({})[]])
caratteri finiti!
|
pila.empty() è true
|
|
true |
stringa |
operazione |
stack (dopo operazione) |
esito |
([({)}[]])
^
c
|
Stack<String> pila = new Stack<String>();
pila.push("(");
|
|
|
...
|
...
|
...
|
|
([({)}[]])
^
c
|
pila.push("{");
|
|
|
([({)}[]])
^
c
|
pila.empty() è false
c' = pila.pop(); ovvero c' = "{"
c match c' è false
|
|
false |
|