C++简单计算器的实现

语言 C++

工具

  • stack
  • map

步骤

  1. 初始化
  2. 读取字符串
  3. 去空格
  4. 负号处理
  5. 判断为空
  6. 检查格式
  7. 计算

示例C++简单计算器的实现

代码

#include <iostream>
#include <string>
#include <stdio.h>
#include <stack>
#include <map>
#include <math.h>
#include <stdlib.h>
#include <sstream>
using namespace std;

char op[8][8];
map<char, int> m;
void init()
{
    m['+'] = 1, m['-'] = 2, m['*'] = 3, m['/'] = 4, m['('] = 5, m[')'] = 6, m['#'] = 7;
    op[1][1] = '>', op[1][2] = '>', op[1][3] = '<', op[1][4] = '<', op[1][5] = '<', op[1][6] = '>', op[1][7] = '>';
    op[2][1] = '>', op[2][2] = '>', op[2][3] = '<', op[2][4] = '<', op[2][5] = '<', op[2][6] = '>', op[2][7] = '>';
    op[3][1] = '>', op[3][2] = '>', op[3][3] = '>', op[3][4] = '>', op[3][5] = '<', op[3][6] = '>', op[2][7] = '>';
    op[4][1] = '>', op[4][2] = '>', op[4][3] = '>', op[4][4] = '>', op[4][5] = '<', op[4][6] = '>', op[2][7] = '>';
    op[5][1] = '<', op[5][2] = '<', op[5][3] = '<', op[5][4] = '<', op[5][5] = '<', op[5][6] = '=';
    op[6][1] = '>', op[6][2] = '>', op[6][3] = '>', op[6][4] = '>', op[6][6] = '>', op[6][7] = '>';
    op[7][1] = '<', op[7][2] = '<', op[7][3] = '<', op[7][4] = '<', op[7][5] = '<', op[7][7] = '=';
}
double operate(double num1, char oper, double num2)
{	
	if(oper == '+')
		return num1 + num2;
	if(oper == '-')
		return num1 - num2;
	if(oper == '*')
		return num1 * num2;
	if(oper =='/')
		return num1 / num2;
}
string trim(string str)
{
	index = 0;
	if(!str.empty()){
		while((index = str.find(' ',index) != string::nops)
			str.erase(index,1);
	}
	return str;
}
string change(string str)
{
	int start;
	start += "#";
	for(int i = 0; i < str.length(); i++){
		if(str[i] == '-'){
			if(i == 0 || i != 0 && (m[str[i-1]] >= 1 && m[str[i-1]] <= 5
				&& str[i+1] >= '0' && str[i+1] <= '9'){
				str += "   ";
				int j = i+1;
				start = j;
				while(m[str[j]] == 0)
					j++;
					
				for(int k = str.length() - 1; k >= j; k--)
					str[k] = str[k-3];
				
				str[i] = '(', str[i+1] = '0', str[i+2] = '-';
				
				int l = i+3;
				string s = str.substr(start, j - start);
				for(int k = 0; k < s.length(); k++)
					str[l+k] = s[k];
					 
				str[l+s.length()] = ')';
			}		
		}
	}
	str.erase(str.length()-1, 1);
	return str;
}
bool test(string str)
{
	bool ifOK = true;
	int flag = 0;
	stack<char> s;
	int start, e;
	str += "#";
	for(int i = 0; i < str.length(); i++){
		//判断非法字符
		if((str[i] < '0' || str[i] > '9') && m[str[i]] == 0 && str[i] != '.')
			return false;
		if(str[i] == '#' && i!= str.length()-1)
			return false;

		//判断小数点
		if(m[str[i]] == 0){
			if(flag == 0){
				start = i;
				flag = 1;
			}
		}
		if(m[str[i]] != 0){
			if(flag == 1){
				e = i;
				string st = str.substr(start, e - start);
				int pointNum = 0;
				if(st[0] == '.') return false;
				for(int j = 0; j < st.length(); j++){
					if(st[j] == '.') pointNum++;
				}
				if(pointNum > 1) return false;
				
			}
			flag = 0;
		}

		//判断运算符
		if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/'){
			if(i == 0) return false;
			if((str[i-1] < '0' || str[i-1] > '9') && str[i-1] != ')') return false;
			if((str[i+1] < '0' || str[i+1] > '9') && str[i+1] != '(') return false;
		}

		//判断括号
		if(str[i] == '(')
			s.push(str[i]);
		if(str[i] == ')'){
			if(s.empty()) return false;
			char c = s.top();
			if(c == '(')
				s.pop();
			else
				return false;
		}
	}
	//判断括号
	if(!s.empty())
		ifOK = false;
	return ifOK;

}

void caculate(string str)
{
	str += "#";
	int flag = 0;
	int start, e;
	stack<double> numStack;//操作数栈
	stack<char> operStack;//运算符栈
	operStack.push('#');
	int i = 0;

	while(str[i] != '#' || operStack.top() != '#'){
		if(m[str[i]] == 0){
			if(flag == 0){
			start = i;
			flag = 1;
			}
		}
		else{
			if(flag == 1){
				e = i;
				//string 转 double
				stringstream s (str.substr(start, e - start));
				double num;
				s >> num;
				
				numStack.push(num);
				flag = 0;
			}
			char c = operStack.top;
			if(op[m[c]][m[str[i]]] == '<'){
				operStack.push(str[i]);
				i++;
			}
			else if(op[m[c]][m[str[i]]] == '='){
				operStac.pop();
				i++;
			}
			else{
				char oper = operStack.top();
				operStac.pop();
				double num2 = numStack.top();
				numStack.pop();
				double num1 = numStack.top();
				numStack.pop();
				double result = operate(num1, oper, num2);
				numStack.push(result);
			}
		}
		
	}
	printf("\t\t\t= %f\n",numStack.top());
	
}
int main()
{
	init();//初始化
	printf("\n\n\n\t\t\t请输入表达式, 退出请输入end:\n");
	string s;
	getline(cin, s, "\n");//读取字符串
	s = trim(s);//去空格
	s = change(s);//处理负号
	if(s == "end"){
		break;
	}
	else if(s.length() > 0){//判断为空
		if(!test(s))//检查格式
			printf("\t\t\t格式错误\n");
		else
			caculate(s);//计算
	}
	else{
		printf("\t\t\t输入不能为空\n");
	}
}

有什么错误或者疑问请下方留言或加微信g1807069286