A simple calculator
Title Link Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Problem Description
Read in a non negative integer evaluation expression containing only +, -, *, /, and evaluate the value of the expression.
Input
The test input contains several test cases, each of which takes up one line, with no more than 200 characters in each line. Integers and operators are separated by a space. There is no illegal expression. When there is only 0 in a row, the input ends and the corresponding result does not output.
Output
Output 1 line for each test case, that is, the value of the expression, accurate to 2 decimal places.
Sample Input
1 + 2
4 + 2 * 5 - 7 / 11
0
Sample Output
3.00
13.36
If you only want to see the code of AC, please slide to the end and see the code of the last code block.
Although this problem is a water problem, it is also fatal to do it! Actually wrote for nearly an hour, in the final analysis, or their own dishes!!!
The first problem is how to read it! So in the beginning I wrote:
#include<iostream> #include<cstring> using namespace std; double ans[200]; int main() { //freopen("in.txt", "r", stdin); double num; char c; while(cin>>num, num!=0) { memset(ans, 0, sizeof(ans)); int counts = 0; ans[counts++] = num; int flag = 0; while(1) { switch(getchar()) { case '*':{ cin>>num; ans[counts-1] = ans[counts-1] * num; break; } case '/':{ cin>>num; ans[counts-1] = 1.0 * ans[counts-1] / num; break; } case '-':{ cin>>num; ans[counts++] = 0 - num; break; } case '+':{ cin>>num; ans[counts++] = num; break; } case '\n':{ flag = 1; break; } default:break; } if(flag) break; } double sum = 0.0; for(int i=0;i<counts;i++) sum += ans[i]; printf("%.2lf\n", sum); } return 0; }
After writing, then the problem comes. If you meet the following example, you will die.
0 * 6
0 / 3
Because while (CIN > > num, Num! = 0) {} was directly sentenced to death! Oh, my God.
Not convinced, I immediately improved it, so the second edition came out.
#include<iostream> #include<cstring> using namespace std; int main() { //freopen("in.txt", "r", stdin); string str; getline(cin, str); while(str != "0") { int len = str.length(); double *ans = new double[len];//Integer number char *symbol = new char[len];//Stored symbols int sym_counts = 0; int ans_counts = 0; ans[ans_counts++] = str[0] - '0'; int i=2; while(i < len) { switch(str[i]) { case '*':{ ans[ans_counts-1] = ans[ans_counts-1] * (str[i+2] - '0'); break; } case '/':{ ans[ans_counts-1] = 1.0 * ans[ans_counts-1] / double(str[i+2] - '0'); break; } case '-':{ symbol[sym_counts++] = '-'; ans[ans_counts++] = str[i+2] - '0'; break; } case '+':{ symbol[sym_counts++] = '+'; ans[ans_counts++] = str[i+2] - '0'; break; } } i += 4; } double sum = ans[0]; for(i=0;i<sym_counts;i++) { if(symbol[i] == '+') sum += ans[i+1]; else sum -= ans[i+1]; } printf("%.2lf\n", sum); getline(cin, str); delete []symbol; delete []ans; } return 0; }
After writing, the test samples have passed, I am happy. Timid, did not dare to submit, wrote a few examples to test a few. Here comes the question again, whoa, whoa
4 + 2 * 5 - 7 / 11
It turned out to be 7.00!!!!!
Lovely bug, mmp, I'm here again.
It turns out that
case '/':{ ans[ans_counts-1] = 1.0 * ans[ans_counts-1] / double(str[i+2] - '0'); break; }
Obviously, it's 11. The program written by myself is calculated by 1.
Want me to give up!!! no way... One word "change":
#include<iostream> #include<cstring> using namespace std; int main() { //freopen("in.txt", "r", stdin); string str; getline(cin, str); while(str != "0") { int len = str.length(); double *ans = new double[len]; char *symbol = new char[len]; int sym_counts = 0; int ans_counts = 0; int i=0, temp=0; while(i < len &&str[i] != ' ') { temp = (temp * 10) + (str[i] - '0'); i++; } ans[ans_counts++] = temp; i += 1; char c; while(i < len) { c = str[i]; i += 2; temp = 0; while(i<len && str[i] != ' ') temp = (temp * 10) + (str[i++] - '0'); switch(c) { case '*':{ ans[ans_counts-1] = ans[ans_counts-1] * temp; break; } case '/':{ ans[ans_counts-1] = 1.0 * ans[ans_counts-1] / temp; break; } case '-':{ symbol[sym_counts++] = '-'; ans[ans_counts++] = temp; break; } case '+':{ symbol[sym_counts++] = '+'; ans[ans_counts++] = temp; break; } } i += 1; } double sum = ans[0]; for(i=0;i<sym_counts;i++) { if(symbol[i] == '+') sum += ans[i+1]; else sum -= ans[i+1]; } printf("%.2lf\n", sum); getline(cin, str); delete []symbol; delete []ans; } return 0; }
This version is finally submitted to AC. It's not easy. The following is the condensed version (the code is simplified):
#include<iostream> #include<cstring> using namespace std; int main() { //freopen("in.txt", "r", stdin); string str; getline(cin, str); while(str != "0") { int len = str.length(); double *ans = new double[len]; int ans_counts = 0, i=0, temp=0; while(i < len &&str[i] != ' ')//Take the first integer temp = (temp * 10) + (str[i++] - '0'); ans[ans_counts++] = temp; char c; while(i < len) { c = str[++i];//str[i] is a space, so it needs to be auto incremented first i += 2; temp = 0; while(i < len && str[i] != ' ')//Take down an integer temp = (temp * 10) + (str[i++] - '0'); switch(c) { case '*':{ ans[ans_counts-1] = ans[ans_counts-1] * temp; break; } case '/':{ ans[ans_counts-1] = 1.0 * ans[ans_counts-1] / temp; break; } case '-':{ ans[ans_counts++] = 0 - temp; break; } case '+':{ ans[ans_counts++] = temp; break; } } } for(i=1;i<ans_counts;i++) ans[i] += ans[i-1]; printf("%.2lf\n", ans[ans_counts-1]); getline(cin, str); delete []ans; } return 0; }