简单计算器的实现

时间:2022-12-29 14:48:52

计算器

问题描述: 输入一个简单四则运算表达式字符串,计算该表达式的值 


注: 
1、表达式只含 +, -, *, /, (, ), 四则运算符 
2、表达式数值只包含整数(0-9),每个操作数可以是多位,且不会出现0作为除数的情况 
3、要考虑加减乘除按通常四则运算规定的计算优先级 
4、除法用整数除法,即仅保留除法运算结果的整数部分。比如80/3=26。输入表达式保证无0作为除数情况发生 
5、输入字符串一定是符合题意合法的表达式,其中只包括数字字符和四则运算符字符,除此之外不含其它任何字符,不会出现计算溢出情况


要求实现函数:  
int calculate(int len,char *expStr) 


【输入】 int len: 字符串长度; char *expStr: 表达式字符串; 
【输出】 无 
【返回】 计算结果  
• 示例  
1) 输入:char *expStr = “-3*(-200)-(-3*(-5-2*10)/(4+3-17)*9)” 

      函数返回:663
2) 输入:char *expStr = “8/3*3”

      函数返回:6



#include "stdafx.h"
#include<vector>
#include<deque>
#include<iostream>
using namespace std;


char*vec2char(vector<char>vec, char*str)
{
	char*s = str;
	vector<char>::iterator it;
	it = vec.begin();
	while (it != vec.end())
		*(s++) = *(it++);
	*s = '\0';
	return str;
}

//计算不带括号的表达式的值
int calculate_without_bracket(vector<char>&substr)
{
	vector<char>::iterator it, it1, it2, iter;
	char*str = new char[100];
	it = substr.begin();
	while (it != substr.end())
	{
		deque<int>bb;
		deque<int>::iterator p;
		int aa;
		//因为每次去括号时,都会对多个“-”
		//号进行合并,这里不会出现多于两个“-”相连的情况
		if (*substr.begin() == '-')
		{
			if (*(substr.begin() + 1) == '-')
			{
				substr.erase(substr.begin(), substr.begin() + 2);
				it = substr.begin();
			}
		}
		if (*it == '*' || *it == '/')
		{
			bool flag1 = false;
			bool flag2 = false;
			int f1 = 0, f2 = 0;
			it1 = it - 1;

			int gg = 0;
			while (*it1 - '0' >= 0 && *it1 - '0' <= 9 && it1 - substr.begin() >= 0)
			{
				gg++;
				bb.push_front(*it1 - '0');
				if (it1 == substr.begin())
					break;
				it1--;
			}
			if (it1 != substr.begin())
			{
				if (*it1 == '-')
				{
					if (*(it1 - 1) == '-')
						if (it1 - 1 == substr.begin())
						{
							substr.erase(substr.begin(), substr.begin() + 2);
							it = substr.begin() + gg;
							it1 = substr.begin();
						}
						else
						{
							it1 = it1 - 2;
							substr.erase(it1 + 1, it1 + 3);
							substr.insert(it1 + 1, '+');
							it1 = it1 + 2;
							it = it1 + gg;
						}
					else if (*(it1 - 1) == '+')//这一次的乘除运算之前不可能出现别的“*”或“/”
					{
						it1 = it1 - 2;
						substr.erase(it1 + 1, it1 + 3);
						substr.insert(it1 + 1, '-');
						it1 = it1 + 2;
						it = it1 + gg;
					}
					else
						it1++;
				}

			}
			else if (it1 == substr.begin() && *it1 == '-')
				it1++;
			it2 = it + 1;
			if (*it2 == '-')
			{
				flag1 = true;
				it2++;
			}
			p = bb.begin();
			while (p != bb.end())
			{
				f1 = *p + 10 * f1;
				++p;
			}
			while (it2 != substr.end() && *it2 - '0' >= 0 && *it2 - '0' <= 9)
			{
				f2 = 10 * f2 + (*it2 - '0');
				it2++;
			}
			if (*it == '*')
				aa = f1*f2;
			else
				aa = f1 / f2;
			if (flag1)
				aa = -aa;
			char*ss = new char[100];
			_itoa(aa, ss, 10);
			if (it1 == substr.begin())
			{
				int c = 0;
				substr.erase(it1, it2);
				while (*ss != '\0')
				{
					substr.insert(substr.begin() + c, *ss);
					++ss;
					++c;
				}
				it = substr.begin();
			}
			else
			{
				int c = 0;
				iter = it1 - 1;
				substr.erase(it1, it2);
				while (*ss != '\0')
				{
					substr.insert(iter + 1 + c, *ss);
					++ss;
					++c;
				}
				//substr.insert(iter + 1, aa+'0');
				it = iter + 1;
			}
		}
		else
		{

			it++;
		}
		//if (substr.size() == 1)
		// return (*substr.begin() - '0');
	}
	it = substr.begin();
	while (it != substr.end())
	{

		deque<int>bb;
		deque<int>::iterator p;
		int aa;
		if (*substr.begin() == '-')
		{
			if (*(substr.begin() + 1) == '-')
			{
				substr.erase(substr.begin(), substr.begin() + 2);

			}
			else
			{
				bool flag2 = false;
				int f1 = 0, f2 = 0;
				it1 = substr.begin() + 1;

				while (*it1 - '0' >= 0 && *it1 - '0' <= 9)
				{
					bb.push_back(*it1 - '0');
					it1++;
					if (it1 == substr.end())
					{
						char*src = new char[100];
						return atoi(vec2char(substr, src));
					}
				}

				p = bb.begin();
				while (p != bb.end())
				{
					f1 = *p + 10 * f1;
					++p;
				}
				it = it1;
				it2 = it + 1;
				if (*it2 == '-')//因为每次去括号时,都会对多个“-”
					//号进行合并,这里不会出现多于两个“-”相连的情况
				{
					it2++;
					flag2 = true;
				}
				while (it2 != substr.end() && *it2 - '0' >= 0 && *it2 - '0' <= 9)
				{
					f2 = 10 * f2 + (*it2 - '0');
					it2++;
				}
				if (*it == '+')
					if (flag2)
						aa = -f1 - f2;
					else
						aa = -f1 + f2;
				else
					if (flag2)
						aa = -f1 + f2;
					else
						aa = -f1 - f2;
				char*ss = new char[100];
				_itoa(aa, ss, 10);
				int c = 0;
				substr.erase(substr.begin(), it2);
				while (*ss != '\0')
				{
					substr.insert(substr.begin() + c, *ss);
					++ss;
					++c;
				}
				//substr.insert(substr.begin(), aa + '0');
				it = substr.begin();

			}
		}
		else if
			//因为每次都是从左到右一次只计算两个数,除了第一个符号是“-”外,另一种
			//情况下第一个操作数一定是正数,只需考虑第二个操作数的符号
			(*it == '+' || *it == '-')
		{
			bool flag1 = false;
			int f1 = 0, f2 = 0;
			it1 = it - 1;
			it2 = it + 1;
			if (*it2 == '-')
			{
				flag1 = true;
				it2++;
			}
			while (*it1 - '0' >= 0 && *it1 - '0' <= 9 && it1 - substr.begin() >= 0)
			{
				bb.push_front(*it1 - '0');
				if (it1 == substr.begin())
					break;
				it1--;
			}
			if (it1 != substr.begin())
				it1++;
			p = bb.begin();
			while (p != bb.end())
			{
				f1 = *p + 10 * f1;
				++p;
			}
			while (it2 != substr.end() && *it2 - '0' >= 0 && *it2 - '0' <= 9)
			{
				f2 = 10 * f2 + (*it2 - '0');
				it2++;
			}
			if (*it == '+')
				if (flag1)
					aa = f1 - f2;
				else
					aa = f1 + f2;
			else
				if (flag1)
					aa = f1 + f2;
				else
					aa = f1 - f2;
			char*ss = new char[100];
			_itoa(aa, ss, 10);
			if (it1 == substr.begin())
			{
				int c = 0;
				substr.erase(it1, it2);
				while (*ss != '\0')
				{
					substr.insert(substr.begin() + c, *ss);
					++ss;
					++c;
				}
				//substr.insert(substr.begin(), aa + '0');
				it = substr.begin();
			}
			else
			{
				//iter = it - 2;
				//substr.erase(it - 1, it + 2);
				//substr.insert(iter + 1, aa + '0');
				//it = iter + 1;
				int c = 0;
				iter = it1 - 1;
				substr.erase(it1, it2);
				while (*ss != '\0')
				{
					substr.insert(iter + 1 + c, *ss);
					++ss;
					++c;
				}
				it = iter + 1;
			}

		}
		else
		{
			it++;
		}
	}

	return atoi(vec2char(substr, str));
}





//去括号,每次找到第一对连续匹配的括号,然后用calculate_without_bracket函数
//计算括号里的表达式的值,计算后的结果插入原表达式,返回true。
//如果原表达式没有括号,返回false
bool erase_bracket(vector<char>&str)
{
	int size = str.size();
	bool flag = false;
	int k = 0;
	int m, n;
	vector<char>::iterator it, it1, it2;
	it = str.begin();
	while (k < size)
	{
		if (str[k] == '(')
		{
			m = k;
			k++;
			while (str[k] != '('&&str[k] != ')')
				k++;
			if (str[k] == ')')
			{
				n = k;
				flag = true;
				break;
			}
			else if (str[k] == '(')
			{
				k--;
			}
			
		}
		else
		{
			k++;
		}
	}
	if (flag)
	{
		vector<char>sub;
		for (int i = m+1; i < n ; i++)
			sub.push_back(str[i]);
		calculate_without_bracket(sub);
		it = it + m - 1;
		for (int i = 0; i < n + 1 - m;i++)
		str.erase(it + 1, (it + 2 ));
		int k = 0;
		int len = sub.size();
		while (k < len)
		{
			str.insert(it + k + 1, sub[k]);
			k++;
		}
	}

	return flag;
}



/*vector<char>char2vec(vector<char>&vec, char*str)
{
	while (*str != '\0')
	{
		vec.push_back(*str);
		++str;
	}
	return vec;
}*/


//整体表达式计算函数,每次调用erase_bracket函数先计算括号里的值
//直到消除所有的括号,最后调用calculate_without_bracket计算剩下的无括号表达式的值
int calculate(int len, char *expStr)
{
	vector<char>str;
	for (int i = 0; i < len; i++)
		str.push_back(expStr[i]);
	bool flag = true;

	while (flag)
	{
		flag = erase_bracket(str);
	}

	return calculate_without_bracket(str);

}




int _tmain(int argc, _TCHAR* argv[])
{
	/*vector<int>aa;
	vector<int>::iterator it,ite;
	for (int i = 0; i < 5; i++)
	aa.push_back(i);
	it = aa.begin()+3;
	ite = it -2;
	aa.erase(it-1,it+1);
	aa.insert(ite+1, 9);*/


	vector<char>vec;
	//char2vec(vec, "2+10-30-2*9/4+3-7*9");
	//cout << calculate_without_bracket(vec) << endl;
	//int len=strlen("2+(5-14-2)*9/(4+3-17)*9");
	int len = strlen("-3*(-200)-(-3*(-5-2*10)/(4+3-17)*9)");
	cout << calculate(len, "-3*(-200)-(-3*(-5-2*10)/(4+3-17)*9)");

	system("pause");
	return 0;
}