题目描述:
给定一个字符串描述的算术表达式,计算出结果值。
输入字符串长度不超过100,合法的字符包括”+, -, *, /, (, )”,”0-9”,字符串内容的合法性及表达式语法的合法性由做题者检查。本题目只涉及整型计算。
- 输入描述:
输入算术表达式
- 输出描述:
计算出结果值
- 示例1
- 输入
400+5
- 输出
405
代码实现:
#include <iostream>
#include<stack>
#include <string>
using namespace std;
//区分判断表达式中的操作数和操作符
bool IsOperator(char ch)
{
if (ch == '+' || ch == '-' ||
ch == '*' || ch == '/' ||
ch == '(' || ch == ')' || ch == '#')
return true;
else
return false;
}
//运算符的优先关系 - 核心逻辑,column表示sOperator中的操作符,row表示ch中的操作符
/*'+','-','*','/','(',')','#'*/
int OpPriority[7][7] = /*'+'*/{ { 1, 1, -1, -1, -1, 1, 1},
/*'-'*/ { 1, 1, -1, -1, -1, 1, 1},
/*'*'*/ { 1, 1, 1, 1, -1, 1, 1},
/*'/'*/ { 1, 1, 1, 1, -1, 1, 1},
/*'('*/ {-1,-1, -1, -1, -1, 0, 1},
/*')'*/ { 1, 1, 1, 1, 0, 1, 1},
/*'#'*/ {-1,-1, -1, -1, -1,-1, 0}};
//将运算符转化为数组下标以便进行优先级比较
int ConvertToIndex(char opr)
{
int index;
switch (opr)
{
case '+':
index = 0;
break;
case '-':
index = 1;
break;
case '*':
index = 2;
break;
case '/':
index = 3;
break;
case '(':
index = 4;
break;
case ')':
index = 5;
break;
case '#':
index = 6;
break;
}
return index;
}
//运算符优先级比较
int getPriority(char opr1, char opr2)
{
int index1 = ConvertToIndex(opr1);
int index2 = ConvertToIndex(opr2);
return OpPriority[index1][index2];
}
//进行运算符转化
int Operate(int opnd1, char op, int opnd2)
{
int ret;
switch(op)
{
case '+':
ret = opnd1 + opnd2;
break;
case '-':
ret = opnd1 - opnd2;
break;
case '*':
ret = opnd1 * opnd2;
break;
case '/':
ret = opnd1 / opnd2;
break;
}
return ret;
}
//运算符优先算法
int CaculateExpression(string strExpress)
{
stack<char> sOperator; //操作符栈,处理+ - * / ()运算
stack<int> sNumber; //操作数栈
char ch;
int i = 0;
//标记位 ‘#’
strExpress += "#";
sOperator.push('#');
ch = strExpress[i++];
//如果##配对,表达式求值完成
while (ch != '#' || sOperator.top() != '#')
{
if (!IsOperator(ch))
{
//操作数入栈
int a=0;
while(!IsOperator(ch))
{
a=a*10+ch-'0'; //将String转化为int
ch=strExpress[i++];
}
sNumber.push(a);
}
else
{
//比较栈顶操作符和即将入栈的操作符的优先关系
switch (getPriority(sOperator.top(), ch))
{
case -1://sOperator.top()优先级小于ch
sOperator.push(ch);
ch = strExpress[i++];
break;
case 0: //sOperator.top()优先级等于ch
sOperator.pop();
ch = strExpress[i++];
break;
case 1://sOperator.top()优先级大于ch,先弹出,计算,结果操作数入sOperator
{
char op = sOperator.top();
sOperator.pop();
int num2 = sNumber.top();//第二个操作数在前
sNumber.pop();
int num1 = sNumber.top();
sNumber.pop();
int ret = Operate(num1, op, num2);
sNumber.push(ret);
break;
}
default:
//不会出现
break;
}
}
}//end of while
//操作数栈的唯一元素即为计算结果
return sNumber.top();
}
bool checkParentheses(int iNum)
{
if(iNum<0)
return false;
return true;
}
int main()
{
std::string str;
int result;
while(getline(cin, str))
{
if(str.empty())
{
cout<<"Ilegal Input"<<endl;
continue;
}
bool bLegal=true;
int iParentheses = 0;
int digitNum = 0;
int opNum = 0;
for(int i=0;i<str.size();)
{
if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')
{
opNum++;
i++;
}
else if(str[i]=='(')
{
iParentheses++;
i++;
}
else if(str[i]==')')
{
iParentheses--;
i++;
}
else if(isdigit(str[i]))
{
//操作数入栈
int a=0;
while(isdigit(str[i]))
{
a=a*10+str[i]-'0'; //将String转化为int
i++;
}
digitNum++;
}
else
{
bLegal=false;
break;
}
if(!checkParentheses(iParentheses))
break;
}
/* 括号必须匹配 */
if(iParentheses!=0)
bLegal=false;
/* 输入中 + - * / 的数量和 digit 数量必须匹配*/
if(digitNum != opNum+1)
bLegal=false;
if(bLegal)
{
result=CaculateExpression(str);
cout<<result<<endl;
}
else
cout<<"Ilegal Input"<<endl;
}
return 0;
}