题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1237
简单计算器
Time Limit: 2000/1000 MS Memory Limit: 65536/32768 K
Total Submission(s): 17611 Accepted Submission(s): 6171
Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2
4 + 2 * 5 - 7 / 11
0
Sample Output
3.00
13.36
解题思路:
在这道题中用栈来存储运算符号,用数组来存储数字。对于*/的优先级比+-高,先是将表达式中的乘除运算做完,然后再将栈里面的符号倒到另一个栈里,从头开始做加减运算。
在水题上折腾了很长时间orz,总结一下,主要是在这几个方面出了问题。
1、如果输入数据是1+2*3的形式,那么在还没有计算2*3就遇到\n结束了。所以在函数中加入了判断栈定元素是否为*/的一段程序。
2、最初的想法是cin.peek()检测到是0就结束了,没有考虑到输入如果是0+0的情况。所以在后面判断是第一位为0后面是/0才是真正的结束。
3、当改好了,感觉应该可以了,却怎么也是wa。找到原因是float的精度太低,有效位只有6-7位,果断改成double。
下面是我的代码:
#include<iostream>
#include<memory.h>
#include<stack>
#include<iomanip>
#include<algorithm>
#include<bitset>
#include<string.h>
using namespace std;
#define NUM 250
double divide(char* e)
{
stack<char>signS;
stack<char>addS;
int MulS = 10;
double h[100] = { 0 };
int CountX = 0;
for (int j = 0; e[j] != '\0'; j++)
{
if (e[j] >= 0 + '0'&&e[j] <= 9 + '0')
h[CountX] = h[CountX] * MulS + e[j] - '0';
else
{
if (signS.size() != 0 && signS.top() == '*')
{
h[CountX - 1] *= h[CountX];
h[CountX] = 0;
CountX--;
signS.pop();
}
if (signS.size() != 0 && signS.top() == '/')
{
h[CountX - 1] /= h[CountX];
h[CountX] = 0;
CountX--;
signS.pop();
}
signS.push(e[j]);
CountX++;
}
}
if (signS.size() != 0 && signS.top() == '*')
{
h[CountX - 1] *= h[CountX];
h[CountX] = 0;
CountX--;
signS.pop();
}
if (signS.size() != 0 && signS.top() == '/')
{
h[CountX - 1] /= h[CountX];
h[CountX] = 0;
CountX--;
signS.pop();
}
while (signS.size() != 0)
{
char s = signS.top();
addS.push(s);
signS.pop();
}
for (int i = 1; addS.size() != 0; i++)
{
char s = addS.top();
if (s == '+')
h[0] += h[i];
else h[0] -= h[i];
addS.pop();
}
return h[0];
}
int main()
{
bitset<1>flag = 0;
while (flag == 0)
{
double sum = 0;
char e[NUM];
memset(e, '\0', sizeof(e));
for (int i = 0; i < NUM; i++)
{
char c = cin.peek();
if (c == '\n')
break;
cin >> e[i];
}
if (e[0] == '0'&&e[1] == '\0')
flag = 1;
else {
sum = divide(e);
//cout << sum << endl;
cout << setiosflags(ios::fixed) << setprecision(2) << sum << endl;
}
cin.ignore();
}
return 0;
}
欢迎批评指正!