Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*para as matrizes*/
typedef struct Mat{
int id, lin, col;
double ** data;
struct Mat *prox;
} Matriz;
/*struc para facilitar a funcao*/
typedef struct Cel{
int valor;
struct Cel * prox;
} celula;
celula * inserecel (celula *fila, int t);
int removecel (celula *fila);
/*pilha auxiliar para trasnformar infixa para posfixa*/
typedef struct simb_{
char r;
struct simb_ *prox;
} simb;
void push_simb (simb * topo, char c);
int pop_simb (simb * topo);
#define DIG 10
#define TAM 80
Matriz * acharPeloId(int id2, Matriz *inicio);
Matriz * somamatriz(Matriz *m1, Matriz *m2);
Matriz * multiplicaescalar(Matriz *m1, Matriz *m2);
Matriz * multiplicamatrizes(Matriz *m1, Matriz *m2);
Matriz * diminuimatriz(Matriz *m1, Matriz *m2);
double ** fazermatriz (int l, int c );
Matriz * matrizesentrada (FILE * entrada, Matriz * inicio);
void *mallocX (unsigned int nbytes);
celula * converteParaPosfixa(char * infixa);
Matriz * calculaExpressao(celula * cab, Matriz * inicio );
Matriz * matrizes (Matriz * inicio, Matriz * colocar);
void push_pilha (celula * topo, int c);
int pop_pilha (celula * topo);
int main (int argc, char *argv[])
{
FILE * entrada;
FILE * saida;
char a;
char infixa[TAM+1];
char * infixa2;
Matriz * inicio = NULL; /*lista pra guardar as matrizes*/
int i,j;
celula * cab; /*lista para guardar a posfixa*/
cab=(celula*)mallocX(sizeof(celula));
cab->prox=cab; /*fila circular*/
entrada = fopen (argv[1], "r");
saida = fopen (argv[2], "w");
if (entrada == NULL)
printf ("\nNao encontrei arquivo\n");
fscanf (entrada, "%c", &a);
/*testa se o char é f para terminar de executar o programa*/
while (a!='f') {
/*testa se o char em e se for guarda as matrizes na lista*/
if (a=='m') {
inicio = matrizesentrada (entrada,inicio);
}
/*testa se o char e para começar o calculo das expressoes com as matrizes*/
else {
/*pega a infixa*/
fscanf(entrada, " %c", &infixa[0]);
for (i=1;infixa[i]!='\n';i++)
fscanf(entrada, " %c", &infixa[i]);
infixa[i++]='\0'; /*coloca um final*/
/*converte para posfixa*/
infixa2=&infixa[0];
cab=converteParaPosfixa(infixa2);
inicio= calculaExpressao( cab, inicio );
/*impressao da matriz resultado*/
for (i=0;i<(inicio->lin);i++)
for (j=0;j<(inicio->col);j++)
fprintf(saida, "%lf", (inicio->data)[i][j]);
}
fscanf (entrada, "%c", &a);
}/*fim do while*/
fclose(entrada);
fclose(saida);
free(infixa2);
free(cab);
free(inicio);
return 0;
}
/*expressao que calcula a expressao e retorna o ponteiro apontado para matriz resultado final*/
Matriz * calculaExpressao(celula * cab, Matriz *inicio)
{
Matriz * mat1;
Matriz * mat2;
Matriz * mat3;
celula *pilha=NULL;
int val1, val2, count=1;
while (cab!=NULL){
if (cab->valor>=0) push_pilha(pilha, cab->valor);
else{
val1=pop_pilha(pilha);
val2=pop_pilha(pilha);
if (count>1) val2=1000+count;
}
mat1 = acharPeloId(val1, inicio);
mat2 = acharPeloId(val2, inicio);
/*se a operacao for + chama as funcoes para tal e coloca resultado na lista*/
if (cab->valor==-1) {
mat3= somamatriz(mat1, mat2);
mat3->id=(1000+count);
inicio = matrizes (inicio, mat3);
count++;
}
/*se a operacao for - chama as funcoes para tal e coloca resultado na lista*/
else if (cab->valor==-2) {
mat3= diminuimatriz(mat1, mat2);
mat3->id=(1000+count);
inicio = matrizes (inicio, mat3);
count++;
}
/*se a operacao for * chama as funcoes para tal e coloca resultado na lista*/
else if (cab->valor==-3) {
mat3= multiplicamatrizes(mat1, mat2);
mat3->id=(1000+count);
inicio = matrizes (inicio, mat3);
count++;
}
else if (cab->valor==-4) {
/*se a operacao for . chama as funcoes para tal e coloca resultado na lista*/
mat3= multiplicaescalar(mat1, mat2);
mat3->id=(1000+count);
inicio = matrizes (inicio, mat3);
count++;
}
cab=cab->prox;
}
return inicio;
}
/*transforma uma expressao infixa para posfixa */
celula * converteParaPosfixa(char * infixa)
{
celula *cab; /*cabeça*/
simb *topo;
int i=0,j;
char str [DIG+1],c;
int count,t;
cab=(celula*)mallocX (sizeof (celula));
cab->prox=cab;
topo=(simb*)mallocX(sizeof (simb));
topo->prox=NULL;
while (infixa[i]!='\n')
{
switch(infixa[i]){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': j=0;
while (infixa[i]>='0' && infixa[i]<='9'){
str[j]=infixa[i];
i++;
j++;
count++;
}
if (count==1){t=str[0]-'0';}
else t = atoi(str);
str[j]='\0';
i--;
cab=inserecel(cab,t);
break;
case'(': push_simb (topo, '('); break;
case')': while (topo->prox!=NULL && topo->r=='('){
str[0]=pop_simb(topo);
str[1]='\0';
cab=inserecel(cab,t);
}
if (topo->prox!=NULL) pop_simb(topo);
break;
case '.':
case '*': while (topo->prox!=NULL && topo->r!='(' && topo->r!='+' && topo->r!='-') {
str[0]=pop_simb(topo);
str[1]='\0';
if (str[0]=='*'){ t=-3;}
if (str[0]=='.'){ t=-4;}
cab=inserecel(cab,t);
}
push_simb(topo,infixa[i]);
break;
case ' ': break; /*se for em branco só le o proximo*/
case '+':
case '-':
while (topo->prox!=NULL && topo->r!='(') {
str[0]=pop_simb(topo);
str[1]='\0';
if (str[0]=='+'){ t=-1;}
if (str[0]=='-'){ t=-2;}
cab=inserecel(cab,t);
}
push_simb(topo,infixa[i]);
break;
/*nenhum dos otros casos*/
default: printf ("ERRO NA EXPRESSAO INFIXA \n"); break; } /*fim do switch*/
i++;
} /*fim do while*/
c=pop_simb(topo);
if (c>='0' && c<='9'){ c=c-'0';}
else if ( c=='*') c=-2;
else if ( c=='+') c==-1;
else if ( c=='-') c=-3;
else if ( c=='.') c=-4;
cab=inserecel(cab,c);
return cab;
}
/*testa para nao ocasionar problema de memoria*/
void *mallocX (unsigned int nbytes)
{
void *ptr;
ptr = malloc (nbytes);
if (ptr == NULL) {
printf ("Socorro! malloc devolveu NULL!\n");
exit (EXIT_FAILURE);
}
return ptr;
}
/*função q soma as matrizes e retorna o ponteiro do resultado*/
Matriz * somamatriz(Matriz * m1, Matriz * m2)
{
int i, j;
Matriz * mat3;
mat3->data=fazermatriz((m1->lin),(m1->col));
/*faz a soma das das Matrizes */
for (i=0; i<(m1->lin); i++)
for (j=0;j<(m1->col);j++)
(mat3->data)[i][j]= (m1->data)[i][j] + (m2->data)[i][j];
return mat3;
}
/*função q multiplica 1 matrize pelo escalar e retorna o ponteiro do resultado*/
Matriz * multiplicaescalar(Matriz * m1, Matriz * m2)
{
int i, j;
Matriz * mat3;
mat3->data=fazermatriz(m1->lin,m1->col);
/*faz a multiplicação pelo escalar */
if ((m2->lin)==1 && (m2->col)==1){
for (i=0; i<(m1->lin); i++)
for (j=0;j<(m1->col);j++)
((mat3->data)[i][j])= ((m1->data)[i][j]) * ((m2->data[0][0]));
}
else {
for (i=0; i<(m1->lin); i++)
for (j=0;j<(m1->col);j++)
((mat3->data)[i][j])= ((m2->data)[i][j]) * ((m1->data[0][0]));
}
return mat3;
}
/*função q multiplica as matrizes e retorna o ponteiro resultado*/
Matriz * multiplicamatrizes(Matriz * m1, Matriz * m2)
{
int i, j, v;
Matriz * mat3;
mat3->data=fazermatriz(m1->lin,m2->col);
/*faz a multiplicação das matrizes */
for (i = 0 ; i < (m1->lin); i++ ){
for (j = 0; j < (m2->col); j++) {
(mat3->data)[i][j]=0;
for (v = 0; v < (m1->col); v++)
(mat3->data)[i][j] = (mat3->data)[i][j] + ((m1->data)[i][v] * (m2->data)[v][j]);
}
}
return mat3;
}
/*função q diminui as matrizes e retorna o ponteiro do resultado*/
Matriz * diminuimatriz(Matriz * m1, Matriz * m2)
{
int i, j;
Matriz * mat3;
mat3->data=fazermatriz(m1->lin,m1->col);
/*faz a soma das duas matrizes */
for (i=0; i<(m1->lin); i++)
for (j=0;j<(m1->col);j++)
(mat3->data)[i][j]= (m1->data)[i][j] - (m2->data)[i][j];
return mat3;
}
/*aloca espaço paras matrizes*/
double ** fazermatriz (int l, int c)
{
int i;
double **m;
m=(double **)mallocX(l*sizeof(double*));
for(i=0;i<l;i++)
m[i]=(double*)mallocX(c*sizeof(double));
return m;
}
/*puxa as matrizes do entrada colocando na lista*/
Matriz * matrizesentrada (FILE * entrada,Matriz * inicio)
{
int lin,id,col,i,j;
Matriz * nova;
fscanf(entrada, "%d", &id);
fscanf(entrada, "%d", &lin);
fscanf(entrada, "%d", &col);
nova->lin=lin;
nova->col=col;
nova->id=id;
(nova->prox)=inicio;
nova->data=fazermatriz(lin,col);
for (i=0;i<(nova->lin);i++)
for (j=0;j<(nova->col);j++)
fscanf(entrada, " %f", (&(nova->data)[i][j]));
return nova;
}
/*coloca uma nova struct na lista */
Matriz * matrizes (Matriz * inicio, Matriz * colocar)
{
Matriz * nova;
nova->lin=colocar->lin;
nova->col=colocar->col;
nova->id=colocar->id;
(nova->prox)=inicio;
nova->data=colocar->data;
return nova;
}
/*acha a matriz pelo id associado a ela e retorna o ponteiro q aponta para ela*/
Matriz * acharPeloId(int id2, Matriz *inicio)
{
Matriz * aux;
aux=inicio;
while(aux != NULL && (inicio->id)!=id2)
{
aux=aux->prox;
}
return aux;
}
/*empilha um char c*/
void push_simb (simb * topo, char c)
{
simb *nova;
nova = (simb*) mallocX(sizeof(simb));
nova->r=c;
nova->prox=topo->prox;
topo->prox=nova;
return;
}
/*desempilha e retorna o char desimpilhado*/
int pop_simb (simb * topo)
{
simb *aux;
aux=topo->prox;
aux->r=topo->r;
topo->prox=aux->prox;
free(aux);
return topo->r;
}
/*insere um elemento na fim da lista */
celula * inserecel (celula *fila, int t)
{
celula *nova;
nova = (celula*)mallocX(sizeof(celula));
nova->valor=t;
nova->prox=fila->prox;
fila->prox=nova;
return (nova);
}
/*remove um elemento da lista e retorna o valor que está na celula retirada*/
int removecel (celula *fila)
{
int v;
celula * aux;
aux=fila->prox;
v=aux->valor;
fila->prox=aux->prox;
free(aux);
return v;
}
/*empilha um int c*/
void push_pilha (celula * topo, int c)
{
celula *nova;
nova = (celula*) mallocX(sizeof(celula));
nova->valor=c;
nova->prox=topo->prox;
topo->prox=nova;
return;
}
/*desempilha*/
int pop_pilha (celula * topo)
{
celula *aux;
aux=topo->prox;
aux->valor=topo->valor;
topo->prox=aux->prox;
free(aux);
return topo->valor;
}