///计算器运算加载器
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MaxSize 1000
#define MaxOp 1000
using namespace std;
struct charac //设定运算符优先级
{
char ch; //运算符
int pri; //优先级
};
struct charac lpri[]=//左运算符及优先级
{
{'=',0},
{'(',1},
{'*',5},
{'/',5},
{'+',3},
{'-',3},
{')',8},
{'a',7},//a代表abs
{'q',7},//q代表sqrt
{'%',5},//模运算
{'^',7},
{'!',7}//阶乘
},
rpri[]=//右运算符及优先级
{
{'=',0},
{'(',8},
{'*',4},
{'/',4},
{'+',2},
{'-',2},
{')',1},
{'a',6},
{'q',6},
{'%',4},
{'^',6},
{'!',6}
};
int leftpri(char op) //求左运算符op的优先级
{
int i;
for (i=0; i<MaxOp; i++)
if (lpri[i].ch==op) return lpri[i].pri;
}
int rightpri(char op) //求右运算符op的优先级
{
int i;
for (i=0; i<MaxOp; i++)
if (rpri[i].ch==op) return rpri[i].pri;
}
bool InOp(char ch) //判断ch是否为运算符
{
if (ch=='(' || ch==')' || ch=='+' || ch=='-'|| ch=='*' || ch=='/'||ch=='a'
||ch=='q'||ch=='%'||ch=='^'||ch=='!')
return true;
else
return false;
}
int Precede(char op1,char op2) //op1和op2运算符优先级的比较结果
{
if (leftpri(op1)==rightpri(op2))
return 0;
else if (leftpri(op1)<rightpri(op2))
return -1;
else
return 1;
}
void trans(char *exp,char postexp[])//将算术表达式exp转换成后缀表达式postexp
{
struct
{
char data[MaxSize]; //存放运算符
int top; //栈指针
} op; //定义运算符栈
int i=0; //i作为postexp的下标
op.top=-1;
op.top++; //将'='进栈
op.data[op.top]='=';
while (*exp!='\0') //exp表达式未扫描完时循环
{
if (!InOp(*exp)) //为数字字符的情况或小数
{
while ((*exp>='0' && *exp<='9')||*exp=='.') //判定为数字
{
postexp[i++]=*exp;
exp++;
}
postexp[i++]='#'; //用#标识一个数值串结束
}
else //为运算符的情况
switch(Precede(op.data[op.top],*exp))
{
case -1: //栈顶运算符的优先级低:进栈
op.top++;
op.data[op.top]=*exp;
exp++; //继续扫描其他字符
break;
case 0: //只有括号满足这种情况
op.top--; //将(退栈
exp++;
break;
case 1: //退栈并输出到postexp中
postexp[i++]=op.data[op.top];
op.top--;
break;
}
}
while (op.data[op.top]!='=') //将栈中运算符退到postexp中
{
postexp[i++]=op.data[op.top];
op.top--;
}
postexp[i]='\0'; //给postexp表达式添加结束标识
}
int fact(int n)//阶乘
{
if(n==1)return 1;
return n*fact(n-1);
}
float compvalue(char exp[]) //计算后缀表达式的值
{
struct
{
float data[MaxSize]; //存放数值
int top; //栈指针
} st; //定义数值栈
float d;
char ch;
int t=0; //t作为exp的下标
st.top=-1;
ch=exp[t];
t++;
while (ch!='\0') //exp字符串未扫描完时循环
{
switch (ch)
{
case '!':
st.data[st.top]=fact(st.data[st.top]);
break;
case '^':
st.data[st.top-1]=pow(st.data[st.top-1],st.data[st.top]);
st.top--;
break;
case '%':
st.data[st.top-1]=
(float)(((int)st.data[st.top-1])%((int)st.data[st.top]));
st.top--;
break;
case 'a':
st.data[st.top]=abs(st.data[st.top]);
break;
case 'q':
st.data[st.top]=sqrt(st.data[st.top]);
case'+':
st.data[st.top-1]=
st.data[st.top-1]+st.data[st.top];
st.top--;
break;
case '-':
st.data[st.top-1]=
st.data[st.top-1]-st.data[st.top];
st.top--;
break;
case '*':
st.data[st.top-1]=
st.data[st.top-1]*st.data[st.top];
st.top--;
break;
case '/':
if (st.data[st.top]!=0)
st.data[st.top-1]=
st.data[st.top-1]/st.data[st.top];
else
{
printf("\n\t除零错误!\n");
exit(0); //异常退出
}
st.top--;
break;
default:
d=0;
int flag=0,count=0; //将数字字符转换成数值存放到d中
while ((ch>='0' && ch<='9')||ch=='.') //为数字字符
{
if(ch=='.')flag=1;
if(flag==0)
{
d=10*d+ch-'0';
}
else
{
if(ch<='9'&&ch>='0')
d=d+(ch-'0')/pow(10,count);
count++;
}
ch=exp[t];
t++;
}
st.top++;
st.data[st.top]=d;
}
ch=exp[t];
t++;
}
return st.data[st.top];
}
bool checkbracket(char *exp,int n)
{
int i=0;
bool match=true;
struct
{
char data[MaxSize]; //存放数值
int top; //栈指针
} st;
st.top=-1;
while(i<n&&match)
{
if(exp[i]=='(')
{
st.top++;
st.data[st.top]=exp[i];
}
else if(exp[i]==')')
{
if(st.top!=-1)
if(st.data[st.top]!='(')
match=false;
else st.top--;
else match=false;
}
i++;
}
if(st.top!=-1)
match=false;
return match;
}
bool check(char *exp,int n)
{
int i=0,match=true;
while(*exp!='\0'&&i<n&&match)
{
if((*exp<='9'&&*exp>='0')||*exp=='.'||InOp(*exp)==true)
;
else
match=false;
i++;
}
return match;
}
int main()
{
system("简易计算器");
system("mode con cols=90 ");
printf("=================简易计算器==================\n");
printf(" * 本计算器支持整型、浮点型数运算\n");
printf(" * 本计算器支持四则运算、sqrt,abs\n mod、^运算及阶乘运算\n");
printf(" * abs用a表示,sqrt用q表示\n");
printf(" * ^表示平方,!表示阶乘\n");
printf("==============================================\n");
printf("请输入表达式\n");
char exp[100];
char postexp[MaxSize],c='y';
while(c=='y')
{
gets(exp);
int n=strlen(exp);
if(n==0)printf("没有任何输入,请重新输入\n");
else
{
if(!checkbracket(exp,n))printf("表达式括号不匹配,请重新输入!\n");
else if(!check(exp,n))printf("表达式中出现无法识别符号,请重新输入!\n");
else
{
trans(exp,postexp);
printf("后缀表达式:%s\n",postexp);
printf("表达式的值:%g\n",compvalue(postexp));
}
}
printf("继续请输入y,任意键退出");
scanf("%c",&c);
getchar();
}
return 0;
}