包括可以实现小括号与加减乘除之间的运算符优先级关系。
基本思路
主要使用c++的栈来进行优先级之间的不同判断,暂时并不支持负数的运算,运算结果中出现的负数可以进行运算。
栈分为两个,第一个栈为操作符的栈,第二个栈为运算数字的栈。
同时在程序初始化时,将运算符之间的优先级关系进行初始化
代码部分如下:
int relation[7][7] = {2,2,1,1,1,2,2,
2,2,1,1,1,2,2,
2,2,2,2,1,2,2,
2,2,2,2,1,2,2,
1,1,1,1,1,3,-1,
2,2,2,2,-1,2,2,
1,1,1,1,1,-1,0,
};
数组下标0-6分别表示的运算符为“+,-,*,/,(,),#”
0为到达输入的末尾,1为栈内操作符的优先关系小于栈外操作符的优先关系。
2为栈内操作符的优先关系大于栈外操作符的优先关系,3为两个括号相遇的情况即(与)相遇,此时需要将括号进行消除。
完整代码如下所示:
#include
#include
#include
#include
using namespace std;
using std::string;
string formula;//用户输入的字符串内容
stack <char> operators;//操作符的栈
stack <double> nums;//数字的栈
int relation[7][7] = {2,2,1,1,1,2,2,
2,2,1,1,1,2,2,
2,2,2,2,1,2,2,
2,2,2,2,1,2,2,
1,1,1,1,1,3,-1,
2,2,2,2,-1,2,2,
1,1,1,1,1,-1,0,
};
void menu();//菜单
void inStack();//对字符串入栈操作
int judgeOperator(char c);//判断字符类型
int getSize(char c);//比较运算符的优先关系
char contrast(int s);
double compute(char c,double first,double second);//计算数值
void menu()
{
cout<<"\n\n\n\n\t\t\t\t\t\t\t\t\t简单计算器"<<endl;
cout<<"请输入要计算的内容以'#'结尾:"<<endl;
getline(cin,formula);//得到用户输入的字符串
inStack();
}
void inStack()
{
operators.push('#');//对栈进行初始化一下
char contents[formula.size()];
strcpy(contents,formula.c_str());
int i=0;
for(i=0;i<formula.size();i++)
{
int data = judgeOperator(contents[i]);
if(data==-1)//是数字的
{
int s = i;
while(judgeOperator(contents[s])==-1)
{
s++;
}
int flag=1;
int num=0;//将多位数字字符转换为数字
for(int j=s-1;j>=i;j--)
{
num+=flag*(contents[j]-'0');
flag*=10;
}
i=s-1;
nums.push(num);//将数字压入栈
}
else if(data==1||contents[i]=='#')//是操作符
{
int x = getSize(operators.top());
int y=getSize(contents[i]);
switch(contrast(relation[x][y])){
case '<'://栈顶元素优先权低
operators.push(contents[i]);//进栈
break;
case '=':
operators.pop();//去括号
break;
case '>':
{
char op = operators.top();//退栈并将运算结果入栈
operators.pop();
double first=nums.top();//第一个数
nums.pop();
double second=nums.top();//第二个数
nums.pop();
nums.push(compute(op,first,second));
i--;
break;
}
case '!'://结束标志
{
cout<<"最终结果为:"<<nums.top()<<endl;
break;
}
}
}
else
{
cout<<"others"<<endl;
}
}
}
int judgeOperator(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
{
return 1;//是运算符
}
else if(isdigit(c)!=0)
{
return -1;//是数字
}
return 0;//非法字符
}
int getSize(char c)//得到运算符在数组中的位置
{
switch(c){
case '+':
return 0;break;
case '-':
return 1;break;
case '*':
return 2;break;
case '/':
return 3 ;break;
case '(':
return 4;break;
case ')' :
return 5;break;
case '#':
return 6;break;
}
return -1;
}
char contrast(int s)
{
if(s==0)
{
return '!';//结束符
}
else if(s==1)
{
return '<';
}
else if(s==2)
{
return '>';
}
else if(s==3)
{
return '=';
}
return -4;//输入的内容不存在于数组
}
double compute(char c,double first,double second)
{
double result;
switch(c){
case '+':
result=first+second;
break;
case '-':
result=second-first;
break;
case '*':
result=second*first;
break;
case '/':
result=second/first;
break;
}
return result;
}
int main()
{
menu();
return 0;
}