pilha2

19
Estrutura de Dados – IF63C 1 Professores Vida e Hilton Aplicações de Pilha Objetivo: Ao final da aula o aluno será capaz de: Analisar trechos de código e obter o seu respectivo algoritmo. Empregar pilhas na solução de problemas EXEMPLO 1 O Exemplo 1, a seguir, ilustra uma típica aplicação de pilhas em sua solução. Deseja-se desenvolver um programa que analise uma expressão matemática e identifique qse os elementos separadores de abertura ‘[‘, ‘{‘ e ‘(‘ são encerrados de forma correta com os elementos separadores de encerramento ‘)‘, ‘}‘ e ‘]’. Por simplicidade, o programa não verifica a ordem de emprego desses elementos de abertura. Ou seja, expressões tais como 2 * ( 3 – [ 4+ { 2 + 3 }] ) e 2 * { 3 – ( 4 + [ 2 + 3 ] ) } são consideradas válidas. Por outro lado, expressões tais como 2 * ( 3 – [ 4+5 ) ] são consideradas inválidas, pois o último elemento aberto ‘[‘, posicionado antes do número 4, está sendo encerrado com o ‘)’, posicionado após o número 5. A Figura 1 ilustra essa comparação. Figura 1 – Exemplo de Análise Esperada do Programa. Ou seja, como sugestão, o programa a ser desenvolvido poderá ter uma interface similar à interface exemplificada na Figura 2 a), b), c) e d).

Upload: ronaldo-ramos

Post on 14-Dec-2014

23 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: pilha2

Estrutura de Dados – IF63C 1 Professores Vida e Hilton

Aplicações de Pilha

Objetivo: Ao final da aula o aluno será capaz de: • Analisar trechos de código e obter o seu respectivo algoritmo. • Empregar pilhas na solução de problemas

EXEMPLO 1 O Exemplo 1, a seguir, ilustra uma típica aplicação de pilhas em sua solução. Deseja-se desenvolver um programa que analise uma expressão matemática e identifique qse os elementos separadores de abertura ‘[‘, ‘{‘ e ‘(‘ são encerrados de forma correta com os elementos separadores de encerramento ‘)‘, ‘}‘ e ‘]’.

Por simplicidade, o programa não verifica a ordem de emprego desses elementos de abertura. Ou seja, expressões tais como 2 * ( 3 – [ 4+ { 2 + 3 }] ) e 2 * { 3 – ( 4 + [ 2 + 3 ] ) } são consideradas válidas.

Por outro lado, expressões tais como 2 * ( 3 – [ 4+5 ) ] são consideradas inválidas, pois o último elemento aberto ‘[‘, posicionado antes do número 4, está sendo encerrado com o ‘)’, posicionado após o número 5. A Figura 1 ilustra essa comparação.

Figura 1 – Exemplo de Análise Esperada do Programa.

Ou seja, como sugestão, o programa a ser desenvolvido poderá ter uma interface similar à interface exemplificada na Figura 2 a), b), c) e d).

Page 2: pilha2

Estrutura de Dados – IF63C 2 Professores Vida e Hilton

Figura 2 – Exemplo de Execução do Programa do Exemplo 1.

No Quadro 1, um programa que realiza a análise 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 matemati ca: 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;

Page 3: pilha2

Estrutura de Dados – IF63C 3 Professores Vida e Hilton

12. void inicializa()

13. { separador = (struct PILHA *) malloc(sizeof(st ruct PILHA));

14. separador->next= NULL ;

15. }

16. void insira(char v)

17. {

18. struct PILHA *novo = (struct PILHA *) malloc(si zeof(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(si zeof(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 == '}')

Page 4: pilha2

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 vali da!");}

73. else {printf("\nExpressao invalida!");};

74. return TRUE;

75. }

Page 5: pilha2

Estrutura de Dados – IF63C 5 Professores Vida e Hilton

EXEMPLO 2 A seguir, um típico exemplo de aplicação de pilhas. Nesse exemplo, busca-se por um programa que avalia uma expressão pós-fixa conforme ilustrado na Figura 3. O desafio desse exemplo é incrementado pela exigência da expressão matemática poder armazenar números com casa decimal, conforme ilustra a Figura 3. O programa listado no Quadro 2 realiza essa tarefa proposta.

Figura 3 – Exemplo de Execução do Programa pilha4_3.cpp

Tarefa: Analise o programa do Quadro 2 e obtenha o seu respectivo algoritmo. Que tipo de

dado, número ou operação é(são) armazenado(s) na pilha? Quais as limitações 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;

Page 6: pilha2

Estrutura de Dados – IF63C 6 Professores Vida e Hilton

13. int q=0;

14. void inicializa()

15. { separador = (struct PILHA *) malloc(sizeof(st ruct PILHA));

16. separador->next= NULL ;

17. }

18. void insira(float valor)

19. {

20. struct PILHA *novo = (struct PILHA *) malloc(si zeof(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 == '/')

Page 7: pilha2

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<strle n(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 %.3 f =

%.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++;}

Page 8: pilha2

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 !! Di gite 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 PO SFIXA “);

114. printf(“para a analise>");

Page 9: pilha2

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.33 9 */

Page 10: pilha2

Estrutura de Dados – IF63C 10 Professores Vida e Hilton

EXEMPLO 3

Outro exemplo característico do uso de pilhas na sua solução é apresentado a seguir. Deseja-se desenvolver um programa que converta um expressão INFIXA para POSFIXA. A Figura 4 exemplifica uma possível interface. O código desse programa é apresentado no Quadro 3 a seguir.

Figura 4 – Exemplo de execução do programa pilha5.cpp

Nesse programa, uma atenção deve ser dada no trecho de código compreendido entre as linhas 74 a 22 do Quadro 3. A função inToPosFix(char [], char[]) recebe dois argumentos. O primeiro deles é a expressão a ser traduzida ou convertida, o segundo é o resultado dessa tradução ou conversão. A linha 79 especifica que todos os caracteres da expressão fornecida pelo usuário serão analisados. A primeira análise verifica se o caracter é um operador. Outro aspecto que merece atenção é a função de análise da precedência 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 função

inToPosFix e das funções que essa função “chama”. Que tipo de dado, número ou operação é(são) armazenado(s) na pilha? Quais as limitações 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

Page 11: pilha2

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 PI LHA));

17. topo->next=NULL ;

18. }

19. void insira(char v)

20. {

21. struct PILHA *novo = (struct PILHA *) malloc(si zeof(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(si zeof(struct

PILHA));

38. novo = topo->next;

39. topo = topo->next;

40. return novo->valor;

41. }

42. }

Page 12: pilha2

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(si zeof(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 post r[MAXCOLS])

75. {

76. int pos=0;

Page 13: pilha2

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();

Page 14: pilha2

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 PO SFIXA:>");

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 -

Page 15: pilha2

Estrutura de Dados – IF63C 15 Professores Vida e Hilton

EXEMPLO 4 Nesse último exemplo, busca-se integrar o conceito de pilhas com orientação 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 solução apresentada no Quadro 4 deverá ser investigada. A sua execução é

ilustrada na Figura 6. Tarefa: Analise o programa do Quadro 4 e obtenha o respectivo algoritmo da função

char *StackCripto::cript(char *frase). A linha 74 do Quadro 4 possui a seguinte instrução “*v = *v->next;” . O que aconteceria se ponteiros não tivessem sido utilizados, por exemplo, se o código fosse escrito da seguinte maneira “v = v->next; “ ?

Page 16: pilha2

Estrutura de Dados – IF63C 16 Professores Vida e Hilton

Figura 6 – Exemplo de Execução 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) {quantidadeDePi lhas=q; }

25. int StackCripto::getQuantidadeDePilhas(){retu rn

Page 17: pilha2

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[quantidadeDePi lhas];

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 pil ha));

56. v->next= NULL ;

57. }

58. void StackCripto::insira(char valor, struct pil ha *v)

59. {

Page 18: pilha2

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 codificad a:");

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);

Page 19: pilha2

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

Conclusão.

Através dos exemplos, algumas aplicações clássicas do conceito de pilhas foram apresentadas.

Na aula anterior alguns exercícios foram sugeridos como tarefa de casa. Com base nos exemplos apresentados, componha soluções para esses exercícios. Os exercícios apresentados foram: 1. Elaborar um programa em C que converta uma expressão matemática da forma: • prefixa para profixa • infixa para prefixa. • infixa para profixa >>> solucionado no EXEMPLO 3. 2. Elaborar um programa que avalie uma expressão prefixa. Por exemplo: • A expressão * + 2 3 4 resultará 20. • A expressão + * 3 4 * 2 5 resultará 22.