Você está na página 1de 19

Estrutura de Dados IF63C 1

Professores Vida e Hilton



Aplicaes de Pilha

Objetivo: Ao final da aula o aluno ser capaz de:
Analisar trechos de cdigo e obter o seu respectivo algoritmo.
Empregar pilhas na soluo de problemas


EXEMPLO 1

O Exemplo 1, a seguir, ilustra uma tpica aplicao de pilhas em sua soluo.
Deseja-se desenvolver um programa que analise uma expresso matemtica e identifique
qse os elementos separadores de abertura [, { e ( so encerrados de forma correta com
os elementos separadores de encerramento ), } e ].
Por simplicidade, o programa no verifica a ordem de emprego desses elementos de
abertura. Ou seja, expresses tais como 2 * ( 3 [ 4+ { 2 + 3 }] ) e 2 * { 3 ( 4 + [ 2 + 3 ]
) } so consideradas vlidas.
Por outro lado, expresses tais como 2 * ( 3 [ 4+5 ) ] so consideradas invlidas,
pois o ltimo elemento aberto [, posicionado antes do nmero 4, est sendo encerrado
com o ), posicionado aps o nmero 5. A Figura 1 ilustra essa comparao.

Figura 1 Exemplo de Anlise Esperada do Programa.

Ou seja, como sugesto, o programa a ser desenvolvido poder ter uma interface
similar interface exemplificada na Figura 2 a), b), c) e d).
Estrutura de Dados IF63C 2
Professores Vida e Hilton


Figura 2 Exemplo de Execuo do Programa do Exemplo 1.

No Quadro 1, um programa que realiza a anlise ilustrada na Figura 1. As linhas 39
a 44 realizam o armazenamento do separador de abertura. Nas linhas 45 a 55, o programa
verifica, caso o caracter lido seja de encerramento, se o ltimo elemento armazenado na
pilha casa com o caracter lido.

Quadro 1 Programa pilha3.cpp
1. // programa para avaliacao de expressao matematica: pilha3.cpp.
2. #include <conio.h>
3. #include <stdio.h>
4. #include <stdlib.h>
5. #include <string.h>

6. #define TRUE 1;
7. #define FALSE 0;

8. struct PILHA
9. { char valor;
10. struct PILHA *next; } *separador;

11. int q=0;

Estrutura de Dados IF63C 3
Professores Vida e Hilton

12. void inicializa()
13. { separador = (struct PILHA *) malloc(sizeof(struct PILHA));
14. separador->next= NULL ;
15. }
16. void insira(char v)
17. {
18. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
19. novo->valor = v;
20. novo->next = separador->next;
21. separador->next = novo;
22. q++;
23. }

24. char retire()
25. {
26. if (separador->next == NULL)
27. { return 27;}
28. else
29. {
30. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
31. novo = separador->next;
32. separador = separador->next;
33. q--;
34. return novo->valor;
35. }}

36. int verifique(char c)
37. {
38. char guardado;
39. if (
40. ( c == '{')
41. ||( c == '[')
42. ||( c == '(')
43. )
44. {insira(c); return TRUE;}
45. else if (
46. ( c == '}')
Estrutura de Dados IF63C 4
Professores Vida e Hilton

47. ||( c == ']')
48. ||( c == ')')
49. ) {guardado = retire();
50. if (
51. ( (guardado == '(' ) && (c==')' ))
52. || ( (guardado == '[' ) && (c==']' ))
53. || ( (guardado == '{' ) && (c=='}' ))
54. )
55. {return TRUE;}
56. else return FALSE;
57. }
58. else return TRUE;
59. }

60. int main()
61. {
62. char teclado[256];
63. int valida=TRUE;
64. inicializa();
65. printf("\nForneca uma expressao matematica para);
66. printf(" a analise de separadores:");
67. gets(teclado);

68. for (int i = 0; i < strlen(teclado); i++)
69. { valida = verifique(teclado[i]);
70. if (valida == 0 /*FALSE*/) break;
71. }
72. if ((valida)&&(q==0)) {printf("\nexpressao valida!");}
73. else {printf("\nExpressao invalida!");};
74. return TRUE;
75. }

Estrutura de Dados IF63C 5
Professores Vida e Hilton


EXEMPLO 2

A seguir, um tpico exemplo de aplicao de pilhas. Nesse exemplo, busca-se por
um programa que avalia uma expresso ps-fixa conforme ilustrado na Figura 3. O desafio
desse exemplo incrementado pela exigncia da expresso matemtica poder armazenar
nmeros com casa decimal, conforme ilustra a Figura 3. O programa listado no Quadro 2
realiza essa tarefa proposta.


Figura 3 Exemplo de Execuo do Programa pilha4_3.cpp


Tarefa: Analise o programa do Quadro 2 e obtenha o seu respectivo algoritmo. Que tipo de
dado, nmero ou operao (so) armazenado(s) na pilha? Quais as limitaes
desse programa ?

Quadro 2 Programa pilha4_3.cpp
1. // pilha4_3.cpp
2. #include <conio.h>
3. #include <stdio.h>
4. #include <stdlib.h>
5. #include <string.h>
6. #include <math.h>
7. #include <ctype.h>

8. #define TRUE 1;
9. #define FALSE 0;

10. struct PILHA
11. { float valor;
12. struct PILHA *next; } *separador;

Estrutura de Dados IF63C 6
Professores Vida e Hilton

13. int q=0;

14. void inicializa()
15. { separador = (struct PILHA *) malloc(sizeof(struct PILHA));
16. separador->next= NULL ;
17. }

18. void insira(float valor)
19. {
20. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
21. novo->valor = valor;
22. novo->next = separador->next;
23. separador->next = novo;
24. q++;
25. }

26. float retire()
27. {
28. if (separador->next == NULL)
29. { return 0;}
30. else
31. {
32. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
33. novo = separador->next;
34. separador = separador->next;
35. q--;
36. return novo->valor;
37. }
38. }

39. int ehOperador(char v)
40. {
41. int saida = FALSE;
42. if ( (v == '+')
43. ||(v == '-')
44. ||(v == '*')
45. ||(v == '/')
Estrutura de Dados IF63C 7
Professores Vida e Hilton

46. ||(v == '$')
47. ) saida = TRUE;
48. return saida;
49. }
50. float execute (float n1, char op, float n2)
51. {
52. float saida=0;
53. switch (op)
54. { case '+' : saida = n2+n1; break;
55. case '-' : saida = n2-n1; break;
56. case '*' : saida = n2*n1; break;
57. case '/' : saida = n2/n1; break;
58. case '$' : saida = pow(n2,n1); break;
59. }
60. return saida;
61. }

62. int verifique(char c[256])
63. {
64. float n, n1, n2;
65. float resultado;
66. char res[20] ;
67. int i=0,p,p2, contador;
68. while((c[i] != '\0')&&(c[i] != '\n')&&(i<strlen(c)))
69. {
70. if ( ehOperador(c[i]) )
71. {n1=retire();
72. n2=retire();
73. resultado = execute(n1,c[i],n2);
74. printf("\n>Operacao Realizada: %.3f %c %.3f =
%.3f",n2,c[i],n1, resultado);
75. insira(resultado);
76. }
77. else
78. { p = i; n=0;
79. if (c[i] != ' ')
80. { contador=0;
81. while ((isdigit(c[p])) && (c[p] != ' '))
82. { contador++; p++;}
Estrutura de Dados IF63C 8
Professores Vida e Hilton


83. for (int k = i; k < (i+contador); k++)
84. n += pow(10,contador-1-(k-i))*((float)c[k]-'0');

// procura pela casa decimal se houver
85. if ( (((p+1) < strlen(c)) && (c[p]=='.')))
86. { contador=0;
87. p2=p+1;
88. while ((isdigit(c[p2])) && (c[p2] != ' '))
89. { contador++; p2++;}

90. for (int k = (p+1); k < (p+1+contador); k++)
91. n += pow(10,(-1)*(k-p))*((float)c[k]-'0');
92. p=p2;
93. }

94. i = p-1;
95. insira(n); /* insere o numero na pilha !*/
96. }
97. }
98. i++;
99. }
100. return TRUE;
101. }

102. void fim()
103. {
104. printf("\n############# FIM DO PROGRAMA !! Digite uma);
105. printf( tecla para encerrar!");
106. getche();
107. }

108. int main()
109. {
110. char teclado[256];
111. int valida=TRUE;
112. inicializa();
113. printf("\nForneca uma expressao matematica POSFIXA );
114. printf(para a analise>");
Estrutura de Dados IF63C 9
Professores Vida e Hilton

115. gets(teclado);
116. valida=verifique(teclado);
117. printf("\n ****Resultado da Expressao: %.3f", retire());
118. fim();
119. return TRUE;
120. }

121. /*sugestao de entrada para execucao
> 13 42 + 20 5 12 * + * 15 + resultara 4415
> 23.45 56.789 - resultara -33.339 */

Estrutura de Dados IF63C 10
Professores Vida e Hilton


EXEMPLO 3

Outro exemplo caracterstico do uso de pilhas na sua soluo apresentado a seguir.
Deseja-se desenvolver um programa que converta um expresso INFIXA para POSFIXA.
A Figura 4 exemplifica uma possvel interface. O cdigo desse programa apresentado no
Quadro 3 a seguir.


Figura 4 Exemplo de execuo do programa pilha5.cpp

Nesse programa, uma ateno deve ser dada no trecho de cdigo compreendido
entre as linhas 74 a 22 do Quadro 3. A funo inToPosFix(char [], char[]) recebe dois
argumentos. O primeiro deles a expresso a ser traduzida ou convertida, o segundo o
resultado dessa traduo ou converso. A linha 79 especifica que todos os caracteres da
expresso fornecida pelo usurio sero analisados. A primeira anlise verifica se o caracter
um operador. Outro aspecto que merece ateno a funo de anlise da precedncia dos
operadores definida no trecho compreendido entre as linhas 64 a 73.
:

Tarefa: Analise o programa do Quadro 3 e obtenha o respectivo algoritmo da funo
inToPosFix e das funes que essa funo chama. Que tipo de dado, nmero ou
operao (so) armazenado(s) na pilha? Quais as limitaes desse programa ?

Quadro 3 Programa pilha5.cpp
1. // programa pilha5.cpp
2. #include <conio.h>
3. #include <stdio.h>
4. #include <stdlib.h>
5. #include <string.h>
6. #include <math.h>

7. #define TRUE 1;
8. #define FALSE 0;

9. const int MAXCOLS =80;

10. typedef struct PILHA
Estrutura de Dados IF63C 11
Professores Vida e Hilton

11. { char valor;
12. struct PILHA *next; } pilha;

13. pilha *topo;

14. void inicializa()
15. {
16. topo = (struct PILHA *) malloc(sizeof(struct PILHA));
17. topo->next=NULL ;
18. }

19. void insira(char v)
20. {
21. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
22. novo->valor = v;
23. novo->next = topo->next;
24. topo->next = novo;
25. }

26. int ehPilhaVazia()
27. { int saida=FALSE;
28. if (topo->next == NULL) saida=TRUE;
29. return saida;
30. }

31. char retire()
32. {
33. if (topo->next == NULL)
34. {return 27;}
35. else
36. {
37. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
38. novo = topo->next;
39. topo = topo->next;
40. return novo->valor;
41. }
42. }
Estrutura de Dados IF63C 12
Professores Vida e Hilton


43. int ehOperador(char s)
44. {
45. int saida = FALSE;
46. if (
47. (s == '+') ||(s == '*')||(s == '/')||(s == '-')||(s == '$')
48. ||(s == ')') ||(s == '(')
49. )
50. saida = TRUE;
51. return saida;
52. }

53. char quemEstahNoTopo()
54. {
55. if (topo->next == NULL)
56. {return 27;}
57. else
58. {
59. struct PILHA *novo = (struct PILHA *) malloc(sizeof(struct
PILHA));
60. novo = topo->next;
61. return novo->valor;
62. }
63. }

64. int precedencia(char op1, char op2)
65. {
66. int saida=FALSE;
67. if ( ((op1 == '*') || (op1=='/') || (op1=='$'))
68. && (op2 != '$')) saida = TRUE;
69. if (op1==op2) saida = TRUE;
70. if (op2==27) saida = TRUE;
71. if (op1=='(') saida = TRUE;
72. return saida;
73. }
74. void inToPosFix( char infix[MAXCOLS], char postr[MAXCOLS])
75. {
76. int pos=0;
Estrutura de Dados IF63C 13
Professores Vida e Hilton

77. char v;
78. char _v = '\0';
79. for (int i = 0; i < strlen(infix); i++)
80. if (ehOperador(infix[i]))
81. {/***/
82. if (infix[i] != ')')
83. { if (precedencia(infix[i],quemEstahNoTopo()))
84. { insira(infix[i]);
85. if (!( postr[pos-1] == ' ')) postr[pos++]=' ';
86. }
87. else
88. {
89. v = retire();
90. if ( (v != ')') && (v != '(') )
91. { if (!( postr[pos-1] == ' ')) postr[pos++]=' ';
92. postr[pos++] = v;
93. }
94. insira(infix[i]);
95. }
96. }
97. else {
98. v = retire();
99. if ( (v != ')') && (v != '(') )
100. { if (!( postr[pos-1] == ' ')) postr[pos++]=' ';
101. postr[pos++] = v;
102. }
103. v = retire(); if (v != '(') insira(v);
104. }
105. }/***/
106. else {
107. if ((infix[i] == ' ') && ( postr[pos-1] == ' ')){}
108. else
109. { if (!( postr[pos-1] == ' ')) postr[pos++]=' ';
110. postr[pos++] = infix[i];
111. }
112. }
113. ////////////////////////////////////////////////////////
114. while (!ehPilhaVazia())
115. { v = retire();
Estrutura de Dados IF63C 14
Professores Vida e Hilton

116. if ( (v != ')') && (v != '(') && (v!= 27))
117. {
118. if (!( postr[pos-1] == ' ')) postr[pos++]=' ';
119. postr[pos++] = v;
120. }
121. }
122. postr[pos]='\0';
123. }

124. int main()
125. {
126. char infix[MAXCOLS];
127. char postr[MAXCOLS];
128. int pos=0;
129. inicializa();

130. printf("\nDigite expressao INFIXA conversao POSFIXA:>");
131. while ((infix[pos++] = getchar()) != '\n');
132. infix[--pos] = '\0';
133. inToPosFix(infix,postr);
134. printf("\na expressao infixa original eh: %s", infix);
135. printf("\na expressao posfixa eh: %s", postr);
136. }
137. //Sugestao de expressoes :
138. // ((1 - ( 2+3)) * 4)$(5 + 6) => 1 2 3 + - 4 * 5 6 + $
139. // (1+2) * 3 => 1 2 + 3 *
140. // 1+(2*3 + 4) -2 => 1 2 3 * 4 + + 2 -

Estrutura de Dados IF63C 15
Professores Vida e Hilton


EXEMPLO 4

Nesse ltimo exemplo, busca-se integrar o conceito de pilhas com orientao a
objetos. Esse desafio, ilustrado na Figura 5, apresentado pelo professor Leandro Tonietto
na UNISINOS. O programa dever conter uma classe de criptografia baseada em pilhas.


Figura 6 Desafio apresentado pelo professor Leandro Tonietto envolvendo o conceito de
Pilhas e OO.

A soluo apresentada no Quadro 4 dever ser investigada. A sua execuo
ilustrada na Figura 6.

Tarefa: Analise o programa do Quadro 4 e obtenha o respectivo algoritmo da funo
char *StackCripto::cript(char *frase).
A linha 74 do Quadro 4 possui a seguinte instruo *v = *v->next; . O que
aconteceria se ponteiros no tivessem sido utilizados, por exemplo, se o cdigo
fosse escrito da seguinte maneira v = v->next; ?

Estrutura de Dados IF63C 16
Professores Vida e Hilton


Figura 6 Exemplo de Execuo do Programa criptogr.cpp

Quadro 4 Programa criptogr.cpp
1. // criptogr.cpp
2. #include <iostream.h>
3. #include <string.h>
4. #include <stdlib.h>
5. #include <stdio.h>

6. using namespace std;

7. /// DEFINICAO DA CLASSE STACKCRIPTO.
8. class StackCripto {
9. private:
10. int quantidadeDePilhas;
11. struct pilha{char valor;
12. struct pilha *next;} ;
13. public:
14. char *cript(char *frase);
15. char *decript(char *frase);
16. StackCripto(int q);
17. int getQuantidadeDePilhas();
18. private:
19. void inicializa( struct pilha *v);
20. void insira(char valor, struct pilha *v);
21. char retire(struct pilha *v);
22. };

23. //construtor
24. StackCripto::StackCripto(int q) {quantidadeDePilhas=q; }
25. int StackCripto::getQuantidadeDePilhas(){return
Estrutura de Dados IF63C 17
Professores Vida e Hilton

QuantidadeDePilhas;}

26. //metodo publico de criptografia
27. char * StackCripto::cript(char *frase)
28. {
29. char saida[256]; int k=0; int i;
30. strcpy(saida,frase);
31. struct pilha *Pilha = new pilha[quantidadeDePilhas];
32. // inicializa as pilhas
33. for ( i = 0; i < quantidadeDePilhas;i++)
inicializa(&Pilha[i]);
34. k=0;
35. for ( i = 0; i < strlen(frase); i++)
36. {
37. insira(frase[i],&Pilha[k]);
38. if ((k+1) == quantidadeDePilhas) {k=0;}
39. else {k++;}
40. }
41. k=0;
42. for ( i = 0; i < strlen(saida); i++)
43. {
44. saida[i] = retire(&Pilha[k]);
45. if ((k+1) == quantidadeDePilhas) {k=0;}
46. else {k++;}
47. }
48. delete [] Pilha;
49. return saida;
50. }
51. char * StackCripto::decript(char *frase)
52. { return cript(frase); };

53. // metodos de manipulacao de pilhas
54. void StackCripto::inicializa( struct pilha *v)
55. { v = (struct pilha *) malloc(sizeof(struct pilha));
56. v->next= NULL ;
57. }

58. void StackCripto::insira(char valor, struct pilha *v)
59. {
Estrutura de Dados IF63C 18
Professores Vida e Hilton

60. struct pilha *novo = (struct pilha *) malloc(sizeof(struct
pilha));
61. novo->valor = valor;
62. novo->next = v->next;
63. v->next = novo;
64. }

65. char StackCripto::retire(struct pilha *v)
66. {
67. char saida;
68. if ( v->next == NULL)
69. { return 27;}
70. else
71. {
72. struct pilha *novo = (struct pilha *) malloc(sizeof(struct
pilha));
73. novo = v->next;
74. *v = *v->next;
75. saida = novo->valor;
76. delete novo;
77. return saida;
78. }
79. }
80. ///////////// FIM DA CLASSE
81.
82. int main()
83. {
84. char *frase={"a bola eh amarela"};
85. int q=3;
86. printf("\nForneca uma frase para ser codificada:");
87. gets(frase);
88. printf("\nQual a quantidade de pilhas:");
89. scanf("%d",&q);
90. StackCripto pilha = StackCripto(q);
91. printf("\nFrase a ser codificada>%s",frase);
92. strcpy(frase,pilha.cript(frase));
93. printf("\nFrase codificada utilizando %d pilha(s)>%s",q,
frase);

Estrutura de Dados IF63C 19
Professores Vida e Hilton

94. strcpy(frase,pilha.decript(frase));
95. printf("\nFrase descodificada>%s", frase);
96. printf("\n **** FIM!");
97. return 0;
98. }


Concluso.

Atravs dos exemplos, algumas aplicaes clssicas do conceito de pilhas foram
apresentadas.
Na aula anterior alguns exerccios foram sugeridos como tarefa de casa. Com base
nos exemplos apresentados, componha solues para esses exerccios. Os exerccios
apresentados foram:

1. Elaborar um programa em C que converta uma expresso matemtica da forma:
prefixa para profixa
infixa para prefixa.
infixa para profixa >>> solucionado no EXEMPLO 3.

2. Elaborar um programa que avalie uma expresso prefixa. Por exemplo:
A expresso * + 2 3 4 resultar 20.
A expresso + * 3 4 * 2 5 resultar 22.