中缀转后缀表达式
最近学数据结构和算法,老师让我们写算法把任意的中缀表达式(有括号,有加减乘除,无负号)转后缀,并计算它,于是贴出来一篇小文记录一下啦
- 对于一个寻常的数学算式,把它用计算机的思维解出来,就要首先把它化成后缀表达式,如果有了建树思想的话,对中缀转后缀或许更加能理解,把后缀转化成树也是很轻松的事情。
- 这里我用了两个栈,一个是放表达式,一个是放表达式里各个数值、方便计算,二话不多说,贴代码
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define maxSize 90
#define ELETYPE char
//
typedef struct Node {
ELETYPE data;
struct Node *next;
}lNode,*Linklist;
typedef struct nNode {
int data;
struct nNode *next;
}nlNode,*nLinklist;
nLinklist ninitStack(nLinklist top){
top=NULL;
return top;
}
nLinklist npush(nLinklist top,int data)
{
nLinklist node;
node=(nLinklist)malloc(sizeof(nlNode));
if(!node){
return top;
}
else{
node->data=data;
node->next=top;
top=node;
return top;
}
}
nLinklist npop(nLinklist top,int *data)
{
if(top==NULL)
return NULL;
else
{
*data=top->data;
nLinklist node=top;
top=top->next;
free(node);
return top;
}
}
int sum(char tem[],int sizearr[],int numarr[]){
nLinklist top=malloc(sizeof(nlNode));
top=ninitStack(top);
int i=0,count=0,num1=0,num2=0;
while(i!=maxSize)
{
if(tem[i]>='0'&&tem[i]<='9')
{
top=npush(top,numarr[count]);
i+=sizearr[count];
count++;
continue;
}
else if(tem[i]=='+')
{
top=npop(top,&num1);
top=npop(top,&num2);
top=npush(top,num2+num1);
}
else if(tem[i]=='-')
{
top=npop(top,&num1);
top=npop(top,&num2);
top=npush(top,num2-num1);
}
else if(tem[i]=='*')
{
top=npop(top,&num1);
top=npop(top,&num2);
top=npush(top,num2*num1);
}
else if(tem[i]=='/')
{
top=npop(top,&num1);
top=npop(top,&num2);
top=npush(top,num2/num1);
}
i++;
}
top=npop(top,&num1);
printf("%d\n",num1);
return 1;
}
//上边是最后计算算式用到的栈,下面开始转后缀
ELETYPE getData(Linklist top);
Linklist push(Linklist top,ELETYPE data);
Linklist pop(Linklist top,ELETYPE *data);
int isEmpty(Linklist top);
Linklist initStack(Linklist top);
Linklist initStack(Linklist top){
top=NULL;
return top;
}
ELETYPE getData(Linklist top){
if(top==NULL)
return 0;
else
return top->data;
}
Linklist push(Linklist top,ELETYPE data)
{
Linklist node;
node=(Linklist)malloc(sizeof(lNode));
if(!node){
return top;
}
else{
node->data=data;
node->next=top;
top=node;
return top;
}
}
Linklist pop(Linklist top,ELETYPE *data)
{
if(top==NULL)
return NULL;
else
{
*data=top->data;
Linklist node=top;
top=top->next;
free(node);
return top;
}
}
int isEmpty(Linklist top){
if(top==NULL)
return 1;
else
return 0;
}
int compareCharacter(char c1,char c2){
int n1,n2;
switch(c1)
{
case '(': n1= 0;break;
case '+':
case '-': n1= 1;break;
case '*':
case '%':
case '/': n1=2;break;
default : n1=-100;break;
}
switch(c2)
{
case '(': n2= 0;break;
case '+':
case '-': n2= 1;break;
case '*':
case '%':
case '/': n2=2;break;
default : n2=-1;break;
}
if(n1>=n2)
return 1;
else
return 0;
}
Linklist reverse_polish(Linklist top,ELETYPE arr[],int sizearr[],int numarr[]){
char tem[maxSize]={0};
int i=0,count=0;
while(arr[i]!='#')
{
if(arr[i]>='0'&&arr[i]<='9')
{
tem[count++]=arr[i++];
continue;
}
if(arr[i]=='(')
{
top=push(top,arr[i]);
i++;
continue;
}
if(arr[i]=='+'||arr[i]=='-'||arr[i]=='*'||arr[i]=='/'||arr[i]=='%')
{
if(!isEmpty(top)&&compareCharacter(getData(top),arr[i]))
{
while(!isEmpty(top)&&compareCharacter(getData(top),arr[i]))
{if(getData(top)!='(')
top=pop(top,&tem[count]);
count++;
}
}
else {
top=push(top,arr[i]);
i++;
continue;
}
top=push(top,arr[i]);
i++;
}
if(arr[i]==')')
{
while(getData(top)!='(')
top=pop(top,&tem[count++]);
char n=0;
top=pop(top,&n);
i++;
}
}
while(!isEmpty(top))
{
top=pop(top,&tem[count++]);
}
int count2=0;
int count3=0;
int count4=0;
//下边一部分就是把后缀表达式的各个数和运算符分割开来,方便阅读
while(tem[count2]!=0)
{
printf("%c",tem[count2]);
count2++;
if(tem[count2-1]>='0'&&tem[count2-1]<='9')
count3++;
if(tem[count2-1]=='+'||tem[count2-1]=='-'||tem[count2-1]=='*'||tem[count2-1]=='/'&&tem[count2]!=0)
printf(" ");
else if(count3==sizearr[count4]&&tem[count2-1]>='0'&&tem[count2-1]<='9')
{
printf(" ");
count3=0;
count4++;
}
}
tem[count]='\0';
printf("\n");
sum(tem,sizearr,numarr);
return 1;
}
//把一个表达式分解成各个数,并计算各个数的位数,为后面输出表达式及计算表达式的值做铺垫
int *arrAddition(char arr[],int numarr[],int sizearr[]){
int i=0,tem=0,count=0,tem2=0,boole=0;
while(arr[i]!='#')
{
while(arr[i]>='0'&&arr[i]<='9'){
tem++;
i++;
}
for(tem2=tem;tem2>0;tem2--)
{
numarr[count]+=(arr[i-tem2]-48)*pow(10,tem2-1);
sizearr[count]++;
boole=1;
}
if(boole==1)
{
count++;
boole=0;
}
if(arr[i]=='#')
return 0;
i++;
tem=0;
}
return 1;
}
int main(){
char arr[maxSize]={0};
while((scanf("%s",arr))!=EOF)
{
Linklist top=malloc(sizeof(lNode));
int numarr[maxSize]={0},sizearr[maxSize]={0};
top=initStack(top);
arrAddition(arr,numarr,sizearr);
reverse_polish(top,arr,sizearr,numarr);
}
return 1;
}
测试是否正确(表达式最后以#做结尾)