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