主要就是用了栈,可以处理大数、负数、小数。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <math.h>
using namespace std;
struct dnode
{
double var;
dnode *next;
};
typedef dnode *dstack;
struct node
{
char var;
node *next;
};
typedef node *stack;
//判断一个'-'是负号还是减号,若是负号则转化为'_'
char* judge(char *s)
{
int i;
if(s[0]=='-')
s[0]='_';
for(i=1; i<(int)strlen(s); i++)
{
if(s[i]=='('&&s[i+1]=='-')
s[i+1]='_';
}
return s;
}
//处理char的栈的函数声明
int isEmpty(stack s); //判断栈是否为空的函数
void pop(stack s); //弹出栈顶元素
void push(stack s, char x); //压入元素x到栈中
char top(stack s); //返回栈顶元素
stack createStack(); //创建栈
void makeEmpty(stack s);//清空栈
//处理double的栈的函数声明
int disEmpty(dstack s); //判断栈是否为空的函数
void dpop(dstack s); //弹出栈顶元素
void dpush(dstack s, double x); //压入元素x到栈中
double dtop(dstack s); //返回栈顶元素
dstack dcreateStack(); //创建栈
void dmakeEmpty(dstack s);//清空栈
//判断运算符优先级
int priority(char op)
{
if(op=='(')
return 0;
else if(op=='+'||op=='-')//加减
return 1;
else if(op=='*'||op=='/'||op=='%')//乘除和求余
return 2;
else if(op=='_'||op=='^')
return 3;
else
return 0;
}
//用全局变量来存后缀表达式
char postfix[1000]= {0};
int j=0;
//1.将中缀表达式转换为后缀表达式
void midtolast(char ext[],int len)
{
stack symbol;
symbol=createStack();
int i;
int topflag=0;
int numflag=0;
for(i=0; i<len; i++)
{
//遇到小数点直接存入数组postfix
if(ext[i]=='.')
{
postfix[j]='.';
j++;
}
//遇到数字直接输出
else if(ext[i]>='0'&& ext[i]<='9')
{
//以i作为数字分隔符
if(numflag==0)
{
postfix[j]='|';
j++;
numflag=1;
}
postfix[j]=ext[i];
j++;
}
//对'(' 和 ')'的处理
else if(ext[i]=='(')
{
push(symbol,'(');
topflag=0;
}
else if(ext[i]==')')
{
while(top(symbol)!='(')
{
postfix[j]=top(symbol);
j++;
pop(symbol);
}
pop(symbol);
topflag=0;
}
else
{
numflag=0;
//操作符进栈 要进栈的操作符优先级高于栈中的操作符,用topflag来记录并比较优先级
int cur=priority(ext[i]);
if(cur>topflag)
{
push(symbol,ext[i]);
topflag=cur;
}
else
{
while(cur<=topflag)
{
postfix[j]=top(symbol);
j++;
pop(symbol);
topflag=priority(top(symbol));
}
push(symbol,ext[i]);
topflag=cur;
}
}
}
//弹出栈中剩余元素
while(!isEmpty(symbol))
{
postfix[j]=top(symbol);
j++;
pop(symbol);
}
}
//由后缀表达式计算表达式的值
void calculate(char ext[],int len)
{
dstack num;
num=dcreateStack();
int i=0;
double temp;
double num1,num2;
for(i=0; i<len; i++)
{
if(ext[i]=='|')
{
sscanf(&ext[i+1],"%lf",&temp);
dpush(num,temp);
}
else if((ext[i]>='0' && ext[i]<='9') || ext[i]=='.')
{
continue;
}
else
{
switch(ext[i])
{
case '+':
{
num2=dtop(num);
dpop(num);
num1=dtop(num);
dpop(num);
dpush(num,num1+num2);
break;
}
case '-':
{
num2=dtop(num);
dpop(num);
num1=dtop(num);
dpop(num);
dpush(num,num1-num2);
break;
}
case '*':
{
num2=dtop(num);
dpop(num);
num1=dtop(num);
dpop(num);
dpush(num,num1*num2);
break;
}
case '/':
{
num2=dtop(num);
dpop(num);
num1=dtop(num);
dpop(num);
dpush(num,num1/num2);
break;
}
case '_':
{
num2=dtop(num);
dpop(num);
dpush(num,-num2);
break;
}
case '^':
{
num2=dtop(num);
dpop(num);
num1=dtop(num);
dpop(num);
dpush(num,pow(num1,num2));
break;
}
case '%':
{
num2=dtop(num);
dpop(num);
num1=dtop(num);
dpop(num);
dpush(num,(int)num1%(int)num2);
break;
}
}
}
}
cout<<dtop(num);
dpop(num);
}
int main()
{
char initial[1000];
cout<<"请输入中缀表达式:"<<endl;
cin>>initial;
//判断是负号还是减号
judge(initial);
//计算中缀表达式
midtolast(initial,strlen(initial));
cout<<"转换为后缀表达式:"<<endl;
for(int i=0;i<(int)strlen(postfix);i++)
{
if(postfix[i]=='_')
{
cout<<'-';
}
else if(postfix[i]=='|')
{
continue;
}
else
{
cout<<postfix[i];
}
}
cout<<endl;
cout<<"后缀表达式计算结果:"<<endl;
calculate(postfix,j);
}
//处理字符的栈
int isEmpty(stack s)
{
return s->next == NULL;
}
void makeEmpty(stack s)
{
if (s == NULL)
printf("must create stack first\n");
while (!isEmpty(s))
pop(s);
}
stack createStack()
{
stack s = new node;
s->next = NULL;
makeEmpty(s);
return s;
}
void push(stack s,char x)
{
stack stk;
stk=new node;
if (stk == NULL)
printf("no memory\n");
stk->var=x;
stk->next=s->next;
s->next=stk;
}
void pop(stack s)
{
if (isEmpty(s))
printf("stack is empty\n");
else
{
stack stk=s->next;
s->next=s->next->next;
delete stk;
}
}
char top(stack s)
{
if(s->next)
return(s->next->var);
else
return -1;
}
//处理double的栈
int disEmpty(dstack s)
{
return s->next == NULL;
}
void dmakeEmpty(dstack s)
{
if (s == NULL)
printf("must create stack first\n");
while (!disEmpty(s))
dpop(s);
}
dstack dcreateStack()
{
dstack s = new dnode;
s->next = NULL;
dmakeEmpty(s);
return s;
}
void dpush(dstack s,double x)
{
dstack stk;
stk=new dnode;
if (stk == NULL)
printf("no memory\n");
stk->var=x;
stk->next=s->next;
s->next=stk;
}
void dpop(dstack s)
{
if (disEmpty(s))
printf("stack is empty\n");
else
{
dstack stk=s->next;
s->next=s->next->next;
delete stk;
}
}
double dtop(dstack s)
{
if(s->next)
return(s->next->var);
else
return -1;
}