一、目的和要求
1. 掌握栈的使用方法
2. 能够应用栈解决竞赛题目
二、实验内容
表达式的值(NOIP2013普及组)
给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入为一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为0到 231-1之间的整数。输入数据保证这一行只有0-9、+、*这 12种字符。
输出为一个整数,表示这个表达式的值。
当答案长度多于 4 位时,请只输出最后4 位,前导0不输出。
示例1:
输入:
1+1*3+4
输出:
8
示例2:
输入:
1+1234567890*1
输出:
7891
对应洛谷网题目:
[NOIP2013 普及组] 表达式求值 - 洛谷
三、算法思路
(简单的实验可以不写,比如这个实验)
在判断是否需要合并数字时采用的是循环式判断,当连续出现的数字被打断出现符号字符时,终止合并,(都是在栈区外面实现)最后把合并后的数字放入数字栈区顶部。
四、源代码
#include<iostream>
#include<stack>
using namespace std;
char relation[3][3]={{'>','<','>'},{'>','>','>'},{'<','<','='}}; //优先级关系表
longlong int getIndex(char c) //运算符对应优先级关系表的行(列)号
{
switch(c)
{
case '+':
return 0;
case '*':
return 1;
case '\0':
return 2;
default:
return 2;
}
}
char precede(char c1,char c2) //定位找到优先级关系
{
return relation[getIndex(c1)][getIndex(c2)];
}
long long int operate(long long int num1,char ch,long long int num2) //运行一个算术运算
{
long long int result = 0;
switch(ch){
case'+':
result = num1+num2;
break;
case'*':
result = num1*num2;
break;
}
return result;
}
long long int calc(char* exp) //求值的主要部分
{
stack<char> oprStack;
stack<int> numStack;
oprStack.push('\0');
char c = *exp; //当前读取字符
long long int isPrevCharNum; //上一个读到的符号是否为数字
long long int num1,num2,result;
char opr;
while(c!='\0'||oprStack.top()!='\0')
{
if(c>='0'&&c<='9') //把所有连续的数字合并到一起并放入数字栈区顶部
{
isPrevCharNum = 0;
while(c>='0'&&c<='9')
{
isPrevCharNum=isPrevCharNum*10+(c-'0');
exp++;
c=*exp;
}
numStack.push(isPrevCharNum%10000);
}
else //遇到运算符字符,判断是否运算
{
switch(precede(oprStack.top(),c))
{
case '<':
oprStack.push(c);
exp++;
c=*exp;
break;
case '=':
oprStack.pop();
exp++;
c=*exp;
break;
case '>':
num2=numStack.top();
numStack.pop();
num1=numStack.top();
numStack.pop();
opr=oprStack.top();
oprStack.pop();
result=operate(num1,opr,num2);
numStack.push(result%10000);
//long long int 只能保存4位的十进制数,所以除以10000取余
break;
}
}
}
return numStack.top();
}
int main() //主函数实现功能
{
char exp[10000000]; //exp保存输入的算式
cin>>exp;
int r=calc(exp)%10000;
cout<<r<<endl;
}
五、实验结果(截图)
六、小结
1.本题中输入的数字,所以数据类型为longlong int;
2.因为数字在相乘或者加法运算后,数字可能会大于四位,所以每次运算结束放入数字栈区都得除以10000取余,否则输出结果错误