Hangzhou Electric oj1237: simple calculator (water instead of water)

Keywords: Java calculator

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;
}
Published 13 original articles, won praise 8, visited 136
Private letter follow

Posted by modigy on Tue, 28 Jan 2020 07:39:31 -0800