/* Dado a pilha de operandos e um operador, desempilha o número de operandos * necessários para aquela operação, executa a operação e empilha o resultado. */ void ExecutaOperacao(Pilha *polPilha, OrdemOperador op) { Polinomio r; ElemPilha *a, *b; a = VerificaDesempilha(polPilha); /* Operadores unários só precisam de um operando. */ if (op == MenosUnario) { r = MultTermo(a->poli, 0, -1); } else { b = VerificaDesempilha(polPilha); if (op == Soma) { r = SomaPolinomios(b->poli, a->poli); } else if (op == Subtracao) { r = SubPolinomios(b->poli, a->poli); } else { r = MultPolinomios(b->poli, a->poli); } if (b->temp) { LiberaPolinomio(b->poli); } FREE(b); } if (a->temp) { LiberaPolinomio(a->poli); } FREE(a); EmpilhaOperando(polPilha, r, true); }
Polinomio CopiaPolinomio (Polinomio p) /* Retorna uma cópia do polinomio 'p' */ { Polinomio aux, res; aux = CriaPolinomioNulo(); res = SomaPolinomios(p,aux); LiberaPolinomio(aux); return res; } /* CopiaPolinomio */
int main() { char acao; Polinomio v[4]; int k, m, n; int e; float c; Boolean fim = false; /* --------------------------------------------------------------------------- */ do { scanf("%c", &acao); printf("Ação: %c", acao); switch (acao) { case '#': ImprimeComentario(); break; case 'c': case 'C': scanf("%d",&k); printf("%2d",k); ImprimeComentario(); v[k-1] = CriaPolinomioNulo(); break; case 'l': case 'L': scanf("%d",&k); printf("%2d",k); ImprimeComentario(); LiberaPolinomio(v[k-1]); break; case 'n': case 'N': scanf("%d",&k); printf("%2d",k); ImprimeComentario(); if (PolinomioNulo(v[k-1])) printf("Polinomio %d é nulo\n",k); else printf("Polinomio %d não é nulo\n",k); break; case 't': case 'T': scanf("%d%d%f",&k,&e,&c); printf("%2d%3d%5.1f",k,e,c); ImprimeComentario(); InsereTermo(v[k-1],e,c); break; case 'i': case 'I': scanf("%d",&k); printf("%2d",k); ImprimeComentario(); printf("----> "); ImprimePolinomio(v[k-1]); break; case 's': case 'S': scanf("%d%d%d",&k,&m,&n); printf("%2d%2d%2d",k,m,n); ImprimeComentario(); v[k-1] = SomaPolinomios(v[m-1],v[n-1]); break; case 'r': case 'R': scanf("%d%d%d%f",&k,&m,&e,&c); printf("%2d%2d%3d%5.1f",k,m,e,c); ImprimeComentario(); v[k-1] = MultTermo(v[m-1],e,c); break; case 'm': case 'M': scanf("%d%d%d",&k,&m,&n); printf("%2d%2d%2d",k,m,n); ImprimeComentario(); v[k-1] = MultPolinomios(v[m-1],v[n-1]); break; case 'h': case 'H': ImprimeComentario(); printf("\n"); printf("# : comentário\n"); printf("c k : v[k] := 0\n"); printf("l k : Libera v[k]\n"); printf("n k : testa se v[k]=0\n"); printf("t k e c : acrescenta termo (e,c) a v[k]\n"); printf("i k : imprime v[k]\n"); printf("s k m n : v[k] := v[m]+v[n]\n"); printf("r k m e c : v[k] := v[m]*(e,c)\n"); printf("m k m n : v[k] := v[m]*v[n]\n"); printf("x : término\n"); printf("q : término\n"); printf("h : imprime resumo\n"); fim = true; break; case 'x': case 'X': case 'q': case 'Q': ImprimeComentario(); fim = true; break; } /* switch */ } while (!fim); /* Verifica se foram liberados todos os blocos alocados */ bapply(bprint); printf("Processamento terminado\n"); return 0; } /* main */
Polinomio CalcExpr(char* expr) /* Retorna o polinômio referente à expressão dada */ { char aux; Pilha duracell; Polinomio res; ElemPilha *op1, *op2, *final; /* Inicializa Pilha da expressão */ CriaPilha(&duracell); while(*expr != '\0') { if (Operando(*expr)) { /* Empilha polinômio. */ aux = toupper(*expr); EmpilhaOperando(&duracell, vetorPoli[(aux - 'A')], false); } else switch(*expr) { case '+': case '-': case '*': /* Operadores Binários */ /* Desempilha os operandos. */ op2 = VerificaDesempilha(&duracell); op1 = VerificaDesempilha(&duracell); if (op1 == NULL || op2 == NULL) IMPRIME_ERRO(MSG_ERRO_FALTA_OPERANDO); /* Empilha o resultado da Operação. */ if (*expr == '+') EmpilhaOperando(&duracell, SomaPolinomios(op1->poli, op2->poli), true); if (*expr == '-') EmpilhaOperando(&duracell, SubPolinomios(op1->poli, op2->poli), true); if (*expr == '*') EmpilhaOperando(&duracell, MultPolinomios(op1->poli, op2->poli), true); /* Libera a memoria dinâmica necessária. */ if (op1->temp) LiberaPolinomio(op1->poli); if (op2->temp) LiberaPolinomio(op2->poli); FREE(op1); FREE(op2); break; case '~': /* Operador unário */ /* Desempilha o operando. */ op1 = VerificaDesempilha(&duracell); /* Empilha o resultado da Operação. */ EmpilhaOperando(&duracell, MultTermo(op1->poli, 0, -1.0), true); /* Libera a memoria dinâmica necessária. */ if (op1->temp) LiberaPolinomio(op1->poli); FREE(op1); break; default: /* Erro: nenhum operador válido. */ IMPRIME_ERRO(MSG_ERRO_CARACTERE_INVALIDO); } /* Avança para o próximo caractere da expressão. */ expr += 1; } final = VerificaDesempilha(&duracell);
Polinomio CalcExpr(char* expr) { /* Retorna o polinômio referente à expressão dada. */ /* O polinômio devolvido é sempre uma nova cópia, mesmo que a */ /* expressão seja uma variável simples. */ Pilha operacao; ElemPilha *aux1, *aux2; Polinomio temp; CriaPilha(&operacao); printf("Comeca a CalcExpr\n"); /*Faz a leitura da expressão dada, termo por termo, até chegar no final da linha*/ while(*expr != '\0'){ /*Caso a entrada seja um operador*/ if(!Operando(*expr)){ printf("Operando\n"); /*Caso o operador seja binário*/ if(*expr == '+' || *expr == '-' || *expr == '*'){ /*Como é um operador, deve-se utilizar os dois elementos do topo da pilha*/ aux1 = VerificaDesempilha(&operacao); aux2 = VerificaDesempilha(&operacao); /*Caso tente desempilhar mas a pilha ja esta vazia, entao falta operandos*/ if(aux1 == NULL || aux2 == NULL){ IMPRIME_ERRO(MSG_ERRO_FALTA_OPERANDO); } /*Faz a operacao entre os dois elementos desempilhados*/ if(*expr == '+'){ printf("Soma\n"); temp = SomaPolinomios(aux2->poli, aux1->poli); } else if(*expr == '-'){ printf("Sub\n"); temp = SubPolinomios(aux2->poli, aux1->poli); } else if(*expr == '*'){ printf("Multi\n"); temp = MultPolinomios(aux2->poli, aux1->poli); } /*Empilha o elemento resultante das operacoes*/ EmpilhaOperando(&operacao, temp, true); /*Libera os elementos da pilha utilizados*/ if(aux1->temp == true){ LiberaPolinomio(aux1->poli); } if(aux2->temp == true){ LiberaPolinomio(aux2->poli); } FREE(aux1); FREE(aux2); } /*Caso o operador seja unário*/ else if(*expr == '~'){ /*Como é um operador unario, só é nescessario usar o elemento do topo da pilha*/ aux1 = VerificaDesempilha(&operacao); temp = MultTermo(aux1->poli, 0, -1.0); EmpilhaOperando(&operacao, temp, true); /*Desaloca a memoria nescessaria*/ if(aux1->temp == true){ LiberaPolinomio(aux1->poli); } FREE(aux1); } /*Se não entrou em nenhum dos outros casos, a entada é invalida*/ else{ IMPRIME_ERRO(MSG_ERRO_CARACTERE_INVALIDO); } } /*Se a entrada não for um operador, é um polinomio*/ else{ printf("Operador\n"); /*Empilha o elemento apontado na pilha operacao*/ EmpilhaOperando(&operacao, vetorPoli[*expr - 'A'], false); } /*Avança a leitura*/ expr++; } /*Depois de terminar de ler as operacoes retira o ultimo elemento e verifica se a pilha está vazia, se sim, é por que completou as operacoes corretamente, entao retorna esse polinomio */ aux1 = VerificaDesempilha(&operacao); if(PilhaVazia(&operacao)){ temp = aux1->poli; /*Cria um novo polinomio para poder ser retornado caso o elemento retornado seja uma das 5 bases*/ if(aux1->temp == false){ temp = MultTermo(aux1->poli, 0, 1.0); } /*Desaloca o ultima elemento da pilha*/ FREE(aux1); return temp; }else{ /*Se a pilha ainda conter algum elemento*/ IMPRIME_ERRO(MSG_ERRO_FALTA_OPERADOR); } }