简单计算器的实现

#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
#include <cmath>
using namespace std;
typedef string::iterator Iter;
void basicFour(string &); // 用于基础四则运算  
void abord(string &); // 用于处理括号
void insertBrackets(string &); // 用于插入括号
inline double& toDouble(const string &);

int main(){
	string input;
	cin >> input;
	try{
		 abord(input);
	}catch(runtime_error e){
		cout << e.what() << endl;
		system("pause");
		return 1;
	}
	cout << input << endl;
	system("pause");
	return 0;
}

void basicFour(string &str){
	if (str[0] == '-')
		str.insert(0, "0");
	int d = 0;
	for (string::size_type i = 0; i < str.size() - 1; ++i)
		if (!isdigit(str[i]) && !isdigit(str[i + 1]))
			++d;
	int count = 0;
	for (Iter i = str.begin(); i != str.end(); ++i)
		if (*i == '+' || *i == '-' || *i == '*' || *i == '/')
			++count;
	count -= d;
	double *num = new double [count + 1]();
	char *oper = new char [count];
	istringstream change(str);
	for (int i = 0, j = 0, k = 0; j < count + 1; ++i){
		if (!(i % 2))
			change >> num[j++];
		else
			change >> oper[k++];
	}
	for (size_t i = 0; i < count; ++i){
		if ((i + 1) < count && (oper[i] == '+' || oper[i] == '-') && (oper[i + 1] == '*' || oper[i + 1] == '/')){
			switch (oper[i + 1]){
			case '*':
				num [i + 2] *= num[i + 1]; break;
			case '/':
				if (num[i + 2] == 0)
					throw runtime_error("错误,0做分母");
				else
					num[i + 2] = num[i + 1] / num[i + 2]; break;
			}
			switch (oper[i]){
			case '+':
				num[i + 2] += num[i]; break;
			case '-':
				num[i + 2] = num[i] - num[i + 2]; break;
			}
			++i;
		}else{
			switch(oper[i]){
			case '+':
				num [i + 1] += num[i]; break;
			case '-':
				num[i + 1] = num[i] - num[i + 1]; break;
			case '*':
				num[i + 1] *= num[i]; break;
			case '/':
				if (num[i + 1] == 0)
					throw runtime_error("错误,0做分母");
				else
					num[i + 1] = num[i] / num[i + 1]; break;
			}
		}
	}
	ostringstream os;
	os << num[count];
	str = os.str();
	delete [] num, oper;
}

void abord(string &str){
	insertBrackets(str);
	if (str.find("(") != string::npos){
		int flag_1 = str.find_last_of("(")  + 1;
		for (Iter i = str.begin() + flag_1; i < str.end(); ++i){
			if (*i == ')'){
				int flag_2 = i - str.begin();
				string& calc = str.substr(flag_1, flag_2 - flag_1);
				basicFour(calc);
				double c = 0;
				c = toDouble(calc);
				if (flag_1 - 4 >= 0){
					switch(str[flag_1 - 4]){
					case 's':
						c = sin(c); 
						flag_1 -= 4;
						goto a;
					case 'c':
						c = cos(c); 
						flag_1 -= 4;
						goto a;
					case 't':
						c = tan(c); 
						flag_1 -= 4;
						goto a;
					case 'l':
						c = log(c); 
						flag_1 -= 4;
						goto a;	
					}
				}
				if (flag_1 - 2 >= 0 && str[flag_1 - 2] == '^'){
					int count = 0;
					string num;
					if (str[flag_1 - 3] == ')'){
						int p = 1;
						for (int j = flag_1 - 4; j >= 0; --j){
							if (str[j] == ')')
								++p;
							if (str[j] == '(')
								--p;
							if (p == 0){
								count = j;
								break;
							}
						}
						num = str.substr(count + 1, flag_1 - 4 - count);
						abord(num);
						flag_1 = count;
					}else{
						for (int j = flag_1 - 3; j >= 0; --j){
							if (isdigit(str[j]) || str[j] == '.')
								++count;	
							else
								break;
						}
						flag_1 -= (count + 2);
						num = str.substr(flag_1, count);
					}
					c = pow(toDouble(num), c);
				}else
					--flag_1;
a:
				calc.clear();
				ostringstream os;
				os << c <<flush;
				calc = os.str();
				str = str.substr(0, flag_1) + calc + str.substr(flag_2 + 1);
				abord(str);
				break;
			}
			if (i == str.end() - 1)
				throw runtime_error("错误,括号不配对");
		}
	}else if (str.find(")") != string::npos)
		throw runtime_error("错误,括号不配对");
	else
		basicFour(str);
}

void insertBrackets(string &str){
	int count = 0;
	for (int i = str.size(); i != 0; --i){
		if (isdigit(str[i]) || str[i] == '.')
			++count;
		else if(count && (str[i] == 'n' || str[i] == 's' || str[i] == 'g' || str[i] == '^')){
			str.insert(i + 1, "(");
			str.insert(i + count + 2, ")");
		}else if (count && str[i] == '-' && (str[i - 1] == 'n' || str[i - 1] == 's' || str[i - 1] == 'g' || str[i - 1] == '^')){
			str.insert(i, "(");
			str.insert(i-- + count + 2, ")");
		}else
			count = 0;
	}
}

inline double& toDouble(const string &str){
	istringstream is(str);
	double r = 0;
	is >> r;
	return r;
}

一个基于控制台的简单计算器,实现了大部分计算操作,存着里存着,方便以后作业使用。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值