Sobre a falha da função pra identificar formação, a pilha alocada dinamicamente não é liberada e vaza um pouco de memória. Por exemplo, você checa os pares e retorna 1 direto para sinalizar má formação, mas a pilha pode ter memória alocada restante. O outro erro é que o if (pilha) printf("\tExpressao mal formada ") nunca será executado já que a má formação já teve return 1 dentro do loop while
Acredito que o erro seja que você não considerou um caso, de quando você encontra um sinal para fechar mas a pilha está vazia, como acontece em ) -5 + 4 ( por exemplo.
Olá Isabella. Fico feliz com seu feedback, que bom que ajudou na compreensão. Quanto ao problema desse código, darei uma semana para quem acompanha o canal. Quarta-feira da semana que vem posto aqui. Caso tenha interesse há outro vídeo aqui (ua-cam.com/video/_1Ex_Nq8aME/v-deo.html) onde apresento outra aplicação pra pilha simulando recursão. Abraços.
Prof, tentei fazer esse exemplo usando aquela estrutura pilha, mas deu seg fault, e eu fui conferir o debugger e ele deu breakpoint numa linha de código que já tinha funcionado: novo-> proximo = pilha->topo; Quando puder, da uma olhada
if(expr[i]=='('||expr[i]=='['||expr[i]=='{') { push_pilha(pilha1, expr[i]); exibir_pilha(pilha1); } talvez seja nesse trecho, mas não to conseguindo identificar
Olá Gabriel. Você assistiu esta aula toda? No minuto 19:00 eu digo que há um problema neste código e proponho que você tente descobrir qual o problema. Eu apresento a solução na aula 235: ua-cam.com/video/5ZvD0bC1AaE/v-deo.html
foi top a aula , tem como tirar esse ( 0 ou 1 ) do return ? ( não printar ele ) {} Certo }[ Errado ^^^^^^^esse era meu objetivo ta saindo {} certo 0 {] errado 1 ^^^ta saindo assim OBRIGADO de verdade pela aula :D
Sim, basta transformar a função em um procedimento, trocando o int por void e retirando os returns, mas não acho esta uma boa solução. Se você não quer que o código retornado aparece na tela é só não imprimir ele.
Acredito que o erro seria que o bloco da condição *if(!formarPar(x[i], remover->caracter))* nunca será executado. // CODIGO // funcao para verificar se () [] {} formam par. int formaPar (char fechamento, char desempilhar) { switch(fechamento) {
// 1 bem formada ; 0 mal formada. case ')' : desempilhar == '(' ? 1 : 0; break;
case ']' : desempilhar == '[' ? 1 : 0; break;
case '}' : desempilhar == '{' ? 1 : 0; break; } } // funcao para indentificar o caractere e empilhar ou desempilhar, de acordo com o caractere int identificaForm (char x[]) { int i = 0; t_No *pilha = NULL, *remover; while(x[i] != '\0') { if(x[i] == '(' || x[i] == '{' || x[i] == '[') pilha = empilhar(pilha, x[i]); else if(x[i] == ')' || x[i] == '}' || x[i] == ']') { imprimir(pilha); remover = desempilhar(&pilha); // if(!formaPar(x[i], remover->caracter)) { // printf(" EXPRESSÃO MAL FORMADA! "); // return 1; // } free(remover); } i++; } if(pilha) { printf(" EXPRESSAO MAL FORMADA! "); return 1; } printf(" Expressão bem formada! "); return 0;
} Na primeira verifição *if(x[i] == '(' || x[i] == '{' || x[i] == '[')* Se tiver algum desses caracteres, irá empilhar. Já na segunda verificação *else if(x[i] == ')' || x[i] == '}' || x[i] == ']')* Caso tenha alguma desses caracteres irá executar o código -> imprimir(pilha); remover = desempilhar(&pilha); // if(!formaPar(x[i], remover->caracter)) { // o professor utilizou == 0. Mas é só colocar o operador lógico !, que da na mesma // printf(" EXPRESSÃO MAL FORMADA! "); // return 1; // } free(remover); A parte de if(!formaPar(x[i], remover -> caracterer)) sempre vai retornar 0. Por quê? Porque, caso exista algum caractere de fechamento ')', '}', ']'. O nó irá ser desempilhado antes da função ser chamada. Então, nunca vai executar essa parte do código. Ou seja, a função formaPar é irrelevante. A parte do código que irá demonstrar se a expressão de fato é mal ou bem formada é if(pilha) { printf(" EXPRESSAO MAL FORMADA! "); return 1; } printf(" Expressão bem formada! "); return 0; Agora, a fala do colega @blucoder é de fato verdadeira. ) -5 + 4 ), irá dar que é bem formada. Por que, na verificação if(pilha) -> etc. Não irá dar nenhum nó empilhado, consequentemente irá printar bem formada e irá retornar 0. A solução que achei foi. // funcao para indentificar o caractere e empilhar ou desempilhar, de acordo com o caractere int identificaForm (char x[]) { int i = 0; t_No *pilha = NULL, *remover; while(x[i] != '\0') { if(x[i] == '(' || x[i] == '{' || x[i] == '[') pilha = empilhar(pilha, x[i]); else if(x[i] == ')' || x[i] == '}' || x[i] == ']') { // caso exista um caractere de fechamento sem um de abertura, é uma expressão inválida. // fazendo verificação se a pilha é NULL, se for e tiver o caractere ), dará expressão mal formada. if(!pilha) { printf(" Expressao mal formada! "); return 1; } imprimir(pilha); remover = desempilhar(&pilha); free(remover); } i++; } if(pilha) { printf(" EXPRESSAO MAL FORMADA! "); return 1; } printf(" Expressão bem formada! "); return 0; }
Sobre a falha da função pra identificar formação, a pilha alocada dinamicamente não é liberada e vaza um pouco de memória. Por exemplo, você checa os pares e retorna 1 direto para sinalizar má formação, mas a pilha pode ter memória alocada restante. O outro erro é que o if (pilha) printf("\tExpressao mal formada
") nunca será executado já que a má formação já teve return 1 dentro do loop while
Acredito que o erro seja que você não considerou um caso, de quando você encontra um sinal para fechar mas a pilha está vazia, como acontece em ) -5 + 4 ( por exemplo.
Queria muito q fizesse no outro estilo de pilha, sem ponteiro duplo
ótima aula, continue com os vídeos.
Olá Matheus.
Continuarei rsrsrs. Obrigado pelo feedback.
Ótima aula, prof. Não consegui identificar o erro no código, mas pela primeira vez entendi uma aplicação para pilhas.
Olá Isabella. Fico feliz com seu feedback, que bom que ajudou na compreensão.
Quanto ao problema desse código, darei uma semana para quem acompanha o canal. Quarta-feira da semana que vem posto aqui.
Caso tenha interesse há outro vídeo aqui (ua-cam.com/video/_1Ex_Nq8aME/v-deo.html) onde apresento outra aplicação pra pilha simulando recursão.
Abraços.
valew professor!! ótima aula
Valeu Edmilson, obrigado pelo feedback 😃
ótima aula!
essa é a aula 231, o senhor colocou 131. obrigado pela aula.
Aquele momento falha nossa 😅😅😅
Muito obrigado pelo tok Ícaro 👍
da pra reduzie esssa parte do codigo:
case ')':
if(d == '(')
return 1;
else
return 0;
break;
por essa:
case ')':
return (d == '(');
break;
Prof, tentei fazer esse exemplo usando aquela estrutura pilha, mas deu seg fault, e eu fui conferir o debugger e ele deu breakpoint numa linha de código que já tinha funcionado:
novo-> proximo = pilha->topo;
Quando puder, da uma olhada
if(expr[i]=='('||expr[i]=='['||expr[i]=='{')
{
push_pilha(pilha1, expr[i]);
exibir_pilha(pilha1);
}
talvez seja nesse trecho, mas não to conseguindo identificar
Olá Gabriel.
Você assistiu esta aula toda?
No minuto 19:00 eu digo que há um problema neste código e proponho que você tente descobrir qual o problema.
Eu apresento a solução na aula 235: ua-cam.com/video/5ZvD0bC1AaE/v-deo.html
Eu não sei se é isso mesmo o erro, mas aparentemente faltou liberar memória se já acabamos o while e a expressão foi mal formada.
Mas alguém travou na lógica? Eu me perdi.. professor teria algo que possa fazer pra melhorar minha lógica
foi top a aula , tem como tirar esse ( 0 ou 1 ) do return ? ( não printar ele )
{}
Certo
}[
Errado
^^^^^^^esse era meu objetivo
ta saindo
{}
certo
0
{]
errado
1
^^^ta saindo assim
OBRIGADO de verdade pela aula :D
Sim, basta transformar a função em um procedimento, trocando o int por void e retirando os returns, mas não acho esta uma boa solução. Se você não quer que o código retornado aparece na tela é só não imprimir ele.
Acredito que o erro seria que o bloco da condição *if(!formarPar(x[i], remover->caracter))* nunca será executado.
// CODIGO
// funcao para verificar se () [] {} formam par.
int formaPar (char fechamento, char desempilhar) {
switch(fechamento) {
// 1 bem formada ; 0 mal formada.
case ')' :
desempilhar == '(' ? 1 : 0;
break;
case ']' :
desempilhar == '[' ? 1 : 0;
break;
case '}' :
desempilhar == '{' ? 1 : 0;
break;
}
}
// funcao para indentificar o caractere e empilhar ou desempilhar, de acordo com o caractere
int identificaForm (char x[]) {
int i = 0;
t_No *pilha = NULL, *remover;
while(x[i] != '\0') {
if(x[i] == '(' || x[i] == '{' || x[i] == '[')
pilha = empilhar(pilha, x[i]);
else if(x[i] == ')' || x[i] == '}' || x[i] == ']') {
imprimir(pilha);
remover = desempilhar(&pilha);
// if(!formaPar(x[i], remover->caracter)) {
// printf("
EXPRESSÃO MAL FORMADA!
");
// return 1;
// }
free(remover);
}
i++;
}
if(pilha) {
printf("
EXPRESSAO MAL FORMADA!
");
return 1;
}
printf("
Expressão bem formada!
");
return 0;
}
Na primeira verifição *if(x[i] == '(' || x[i] == '{' || x[i] == '[')*
Se tiver algum desses caracteres, irá empilhar.
Já na segunda verificação *else if(x[i] == ')' || x[i] == '}' || x[i] == ']')*
Caso tenha alguma desses caracteres irá executar o código
-> imprimir(pilha);
remover = desempilhar(&pilha);
// if(!formaPar(x[i], remover->caracter)) { // o professor utilizou == 0. Mas é só colocar o operador lógico !, que da na mesma
// printf("
EXPRESSÃO MAL FORMADA!
");
// return 1;
// }
free(remover);
A parte de if(!formaPar(x[i], remover -> caracterer)) sempre vai retornar 0. Por quê? Porque, caso exista algum caractere de fechamento ')', '}', ']'. O nó irá ser desempilhado antes da função ser chamada. Então, nunca vai executar essa parte do código. Ou seja, a função formaPar é irrelevante.
A parte do código que irá demonstrar se a expressão de fato é mal ou bem formada é
if(pilha) {
printf("
EXPRESSAO MAL FORMADA!
");
return 1;
}
printf("
Expressão bem formada!
");
return 0;
Agora, a fala do colega @blucoder é de fato verdadeira. ) -5 + 4 ), irá dar que é bem formada. Por que, na verificação if(pilha) -> etc. Não irá dar nenhum nó empilhado, consequentemente irá printar bem formada e irá retornar 0. A solução que achei foi.
// funcao para indentificar o caractere e empilhar ou desempilhar, de acordo com o caractere
int identificaForm (char x[]) {
int i = 0;
t_No *pilha = NULL, *remover;
while(x[i] != '\0') {
if(x[i] == '(' || x[i] == '{' || x[i] == '[')
pilha = empilhar(pilha, x[i]);
else if(x[i] == ')' || x[i] == '}' || x[i] == ']') {
// caso exista um caractere de fechamento sem um de abertura, é uma expressão inválida.
// fazendo verificação se a pilha é NULL, se for e tiver o caractere ), dará expressão mal formada.
if(!pilha) {
printf("
Expressao mal formada!
");
return 1;
}
imprimir(pilha);
remover = desempilhar(&pilha);
free(remover);
}
i++;
}
if(pilha) {
printf("
EXPRESSAO MAL FORMADA!
");
return 1;
}
printf("
Expressão bem formada!
");
return 0;
}