赛码网基础算法——简单计算(求解加减乘除等复杂算式)
2017-04-11 19:54
447 查看
题目转自赛码网
为方便用户使用,他们打算为用户提供一个简单计算功能,用户输入数学算式,就可以得到计算结果。
其中涉及的计算包括:”+”、”-”、”*”、”/”、”^”、”(”、”)”,分别表示加减乘除和指数,其中括号用于调整计算的顺序。合法的表达式如下:
x+y+z
x+(y+z)
x*(y+z)+a-b-c^d
小赛对此不太精通,因此请你帮忙编写这个程序。
输入
输入数据有多行,每行为一个用户输入的算式,保证算式是合法的,每行最多包含不超过200个字符。所有参与运算的数值均为整数,若为指数,则为正整数。
输出
对每个算式,在单独的一行中输出计算结果,结果请输出整数。
样例输入
1+2+3+4+5+6+7+8+9+10
1+2*3+4
1+2^(3+3)+5
样例输出
55
11
70
回到正题,从整个题结构来看,因为我们学习了运算法则,运算符的优先级我们很熟悉,所以能够按顺序很快计算出来。但是计算机是死的,所以需要解决的一个难题就是怎么设计规则,让计算机“知道”运算优先级。其实这块有个规则,先后两个运算符,如果后者比前者运算符优先级低的话,前者就可以正常进行计算,计算完事再进行下一次比较。反之则暂且不考虑计算,继续往公式序列后面遍历。
说到这里,也很显然可以看出,该题适合的数据结构是栈(stack),一旦没有出现前后两个运算符满足后者比前者优先级低的条件,我就将遍历到的序列压入栈中,等到下一步取数。说的不太清楚,详细还是看下面的程序吧。
个人学习记录,由于能力和时间有限,如果有错误望读者纠正,谢谢!
1、题目:
小赛所在的小组主要负责WEB应用的开发工作,这次他所在的小组正在开发一个WEB版的财务软件。为方便用户使用,他们打算为用户提供一个简单计算功能,用户输入数学算式,就可以得到计算结果。
其中涉及的计算包括:”+”、”-”、”*”、”/”、”^”、”(”、”)”,分别表示加减乘除和指数,其中括号用于调整计算的顺序。合法的表达式如下:
x+y+z
x+(y+z)
x*(y+z)+a-b-c^d
小赛对此不太精通,因此请你帮忙编写这个程序。
输入
输入数据有多行,每行为一个用户输入的算式,保证算式是合法的,每行最多包含不超过200个字符。所有参与运算的数值均为整数,若为指数,则为正整数。
输出
对每个算式,在单独的一行中输出计算结果,结果请输出整数。
样例输入
1+2+3+4+5+6+7+8+9+10
1+2*3+4
1+2^(3+3)+5
样例输出
55
11
70
2、解析:
这个题目是一个基本算法题,但是挺费时间,需要考虑很多细节,如果出在某个IT公司笔试题中,我估计我会答不完。回到正题,从整个题结构来看,因为我们学习了运算法则,运算符的优先级我们很熟悉,所以能够按顺序很快计算出来。但是计算机是死的,所以需要解决的一个难题就是怎么设计规则,让计算机“知道”运算优先级。其实这块有个规则,先后两个运算符,如果后者比前者运算符优先级低的话,前者就可以正常进行计算,计算完事再进行下一次比较。反之则暂且不考虑计算,继续往公式序列后面遍历。
说到这里,也很显然可以看出,该题适合的数据结构是栈(stack),一旦没有出现前后两个运算符满足后者比前者优先级低的条件,我就将遍历到的序列压入栈中,等到下一步取数。说的不太清楚,详细还是看下面的程序吧。
3、程序:
#include<iostream> #include<cctype> #include<stack> #include<cmath> using namespace std; //建立前后两运算符关系:分别是'\0' , + , - , * , / , ^ , ( , ) //-1表示横对应符号比纵对应运算符优先级小,0表示平等,1表示大 const int cmp_punct[8][8] = { {0,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,-1,-1,-1,1,1,-1}, {-1,-1,-1,-1,-1,-1,1,-1}, {0,1,1,1,1,1,1,0}, {0,-1,-1,-1,-1,-1,-1,-1} }; //对两个数求对应的 int computeResult(int a, char op, int b){ switch(op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; case '^': return pow((double)a,(double)b); } } //获取运算符对应到cmp_punct数组中索引 int getRule(char op) { switch(op) { case '\0': return 0; case '+': return 1; case '-': return 2; case '*': return 3; case '/': return 4; case '^': return 5; case '(': return 6; case ')': return 7; default: return -1; } } int main( ) { char cArr[300]={'\0'}; while(cin.getline(cArr,200)){ int i = 0; stack<int> digit; stack<char> punct; punct.push('\0');//起始端 while(!punct.empty()){ if(isdigit(cArr[i])){ //如果一直是数字,就加载当前数到digit数字栈中 int sum = 0; while(isdigit(cArr[i])){ sum = sum*10 + cArr[i]-'0'; i++; } digit.push(sum); } else{ //如果是符号,就和上一个运算符比较优先级,确定上一个运算符是否展开运算 int first = getRule(punct.top()); int second = getRule(cArr[i]); if(cmp_punct[first][second] == 1){ punct.push(cArr[i++]); } else if(cmp_punct[first][second] == -1){ //新运算符没有上一个运算符优先级高,上一个运算符可以运算了 int a = digit.top(); digit.pop(); int b = digit.top(); digit.pop(); digit.push(computeResult(b, punct.top(), a)); punct.pop(); //删除入栈的运算符 } else{ //等于0则直接删除 punct.pop(); i++; } } } cout<<digit.top()<<endl; } return 0; }
个人学习记录,由于能力和时间有限,如果有错误望读者纠正,谢谢!
转载请注明出处:CSDN 无鞋童鞋。
相关文章推荐
- 算法基础(1)关于时间复杂度计算之函数增长
- 简单理解计算-算法时间复杂度
- 基础算法学习(04)-算法的时间复杂度计算简明笔记
- 单核单线程、单核多线程、多核多线程以及并行计算对大数据和复杂算法的简单效应
- 一个简单的计算素数的算法
- 利用MPICH2计算矩阵相乘的简单算法
- 简单算法系列之完数的计算
- 一个计算平方根的简单算法
- 转载 算法时间复杂度分析基础。
- 算法基础(二)——算法时间复杂度和渐进时间复杂度
- 算法时间复杂度分析基础
- 【刘庆源码共享】稀疏线性系统求解算法MGMRES(m) 之 基础类(Double类,封装double)
- 算法时间复杂度分析基础(转)
- 一个计算简单数学表达式值的算法。
- 一个简单的JavaScript日期计算算法
- 一个简单的JavaScript 日期计算算法
- 计算机视觉计算理论与算法基础-computer vision algorithms and the theoretical calculation based
- 算法的度量-----时间复杂度问题的计算
- 大家都知道π=3.1415926……无穷多位, 历史上很多人都在计算这个数, 一直认为是一个非常复杂的问题。现在有了电脑, 这个问题就简单了。
- 《计算机视觉 : 计算理论与算法基础》(马颂德 & 张正友)扫描版[PDF]