C++计算表达式(支持括号)

继上一篇扩展:文章:C++计算表达式(暂时不支持带括号运算)

这次代码中多了一个新的函数


// 声明 括号处理
extern Token parenthesis_dispose(Token); 

实现

Token parenthesis_dispose(Token tokens) {
	
	Token::iterator begin, end;
	
	Token dispose_part; 
	
	
	for (Token::iterator iter = tokens.begin(); iter != tokens.end(); iter++) {
		
		if (*iter == "(") {
			
			begin = iter;
			
		} else if (*iter == ")") {
			
			end = iter;
			
			for (Token::iterator inline_iter = (begin + 1); inline_iter != end; inline_iter++) {
				
				// TODO 一个新的Token对象储存括号内的tokens,然后调用函数运算得到结果之后山区原来的括号替换成结果 
				dispose_part.push_back(*inline_iter);
			}
			dispose_part = operation(dispose_part);
			
			*end = dispose_part[0];
			
			break;
		}
	}
	
	for (Token::iterator iter = begin; iter != end; iter = iter + 0) {
		
		iter = tokens.erase(iter), end--;
	}
	
	return tokens;
}

当遇到左括号记录下他的位置,当遇到右括号则记录下右括号的位置并截取中间表达式部分。

因为括号获取判断机制所以截取的表达式是最优先计算的部分。

运算完成后删除原表达式和左右括号并将结果放入到原来的表达式,为下面的计算做准备。

完整代码如下


// 基本输出输入 
#include <iostream>

// 储存表达式 tokens 
#include <vector>

// 数字与字符串转换 
#include <sstream>


// 测试专用 
#define ___test_for_tokens \
for (___uint32 index = 0; index < tokens.size(); index++) { \
	 \
	std::cout << tokens[index] << ", "; \
} \
std::cout << std::endl;


// 集合类型 
typedef		signed short			___sint16	;
typedef		unsigned short			___uint16	;
typedef		signed int				___sint32	;
typedef		unsigned int			___uint32	;
typedef		signed long	long		___sint64	;
typedef		unsigned long long		___uint64	;

typedef	typename	std::string					String	;
typedef	class		std::vector<std::string>	Token	;
typedef typename	std::stringstream			Convert	;


// 声明 是否是数字 
extern bool is_digit(char);
// 声明 是否是运算符 
extern bool is_operator(char);
// 声明 删除空格 
extern String delete_space(String);
// 声明 切分token 
extern Token get_token(String);
// 声明 括号处理
extern Token parenthesis_dispose(Token); 
// 声明 string转type x 
template<typename typex> extern typex string_to_typex(String);
// 声明 运算 
extern Token operation(Token);


___sint32 main(___sint32 argument_count, char** arguments) {
	
	String expression;
	
	Token tokens;
	
	
	std::getline(std::cin, expression);
	
	expression = delete_space(expression);
	tokens = get_token(expression);
	
	for (___uint32 index = 0; index < expression.length(); index++) {
		
		if (expression[index] == '(' or expression[index] == ')') {
			
			tokens = parenthesis_dispose(tokens);
			
			break;
		}
	}
	
	while (true) {
		
		for (Token::iterator iter = tokens.begin(); iter != tokens.end(); iter++) {
			
			if (*iter == "(" or *iter == ")") {
				
				goto then;
			}
		}
		break;
		
		then:
			tokens = parenthesis_dispose(tokens);
	}
	
	tokens = operation(tokens);
	
	// 最后结果是token第零个 
	std::cout << tokens[0];
	
	return 0;
}

bool is_digit(char character) {
	
	return character >= '0' and character <= '9';
}

bool is_operator(char character) {
	
	return character == '+' or character == '-' or character == '*' or character == '/';
}

String delete_space(String expression) {
	
	String result;
	
	
	for (___uint32 index = 0; index < expression.length(); index++) {
		
		if (expression[index] == ' ') {
			
			continue;
		
		// 若不是空格则追加	
		} else {
			
			result += expression[index];
		}
	}
	
	return result;
}

Token get_token(String expression) {
	
	Token result;
	
	String buffer_token;
	
	
	for (___uint32 index = 0; index < expression.length(); index++) {
		
		buffer_token = "";
		
		// 数字 
		if (is_digit(expression[index])) {
			
			while (is_digit(expression[index])) {
				
				buffer_token += expression[index], index++;
			}
			index--;
			
			result.push_back(buffer_token);
		
		// 符号 
		} else if (is_operator(expression[index])) {
			
			// 如果有两个符号,则认定为 二元运算 和 一元运算
			// 例 37*-92
			// 则 |37|*|-92| 
			if (is_operator(expression[index + 1]) and is_digit(expression[index + 2])) {
				
				buffer_token += expression[index], index++;
				result.push_back(buffer_token), buffer_token = "";
				
				buffer_token += expression[index], index++;
				
				while (is_digit(expression[index])) {
					
					buffer_token += expression[index], index++;
				}
				index--;
				
				result.push_back(buffer_token);
			
			// 如果只有一个符号,则认为是 二元运算
			// 例 38*23
			// 则 |38|*|23|	
			} else {
				
				buffer_token += expression[index];
				
				result.push_back(buffer_token);
			}
			
		} else if (expression[index] == '(' or expression[index] == ')') {
			
			buffer_token += expression[index];
			
			result.push_back(buffer_token);
		}
	}
	
	return result;
}

Token parenthesis_dispose(Token tokens) {
	
	Token::iterator begin, end;
	
	Token dispose_part; 
	
	
	for (Token::iterator iter = tokens.begin(); iter != tokens.end(); iter++) {
		
		if (*iter == "(") {
			
			begin = iter;
			
		} else if (*iter == ")") {
			
			end = iter;
			
			for (Token::iterator inline_iter = (begin + 1); inline_iter != end; inline_iter++) {
				
				// TODO 一个新的Token对象储存括号内的tokens,然后调用函数运算得到结果之后山区原来的括号替换成结果 
				dispose_part.push_back(*inline_iter);
			}
			dispose_part = operation(dispose_part);
			
			*end = dispose_part[0];
			
			break;
		}
	}
	
	for (Token::iterator iter = begin; iter != end; iter = iter + 0) {
		
		iter = tokens.erase(iter), end--;
	}
	
	return tokens;
}

template<typename typex> typex string_to_typex(String string) {
	
	Convert convert;
	
	typex value;
	
	
	convert << string, convert >> value;
	
	return value;
}

Token operation(Token tokens) {
	
	//
	
	
	// 先扒拉乘除 
	for (Token::iterator iter = tokens.begin(); iter != tokens.end(); iter++) {
		
		if (*iter == "*") {
			
			// 左值,右值,总值 
			___sint32 left = 0, right = 0, ret = 0;
			
			
			// 左值 
			left = string_to_typex<___sint32>(*(iter - 1));
			// 右值 
			right = string_to_typex<___sint32>(*(iter + 1));
			// 总值 
			ret = left * right;
			
			// 把不要的都扔了
			// S								|23|*|89|
			//									    ↑ 
			// iter = tokens.erase(iter - 1);	|*|89|
			//									 ↑ 
			// iter = tokens.erase(iter);		|89|
			//									 ↑ 
			// *iter = std::to_string(ret);		|2047|
			//									 ↑ 
			iter = tokens.erase(iter - 1);
			iter = tokens.erase(iter);
			*iter = std::to_string(ret);
			
		} else if (*iter == "/") {
			
			___sint32 left = 0, right = 0, ret = 0;
			
			
			left = string_to_typex<___sint32>(*(iter - 1));
			right = string_to_typex<___sint32>(*(iter + 1));
			ret = left / right;
			
			iter = tokens.erase(iter - 1);
			iter = tokens.erase(iter);
			*iter = std::to_string(ret);
		}
	}
	
	// 再扒拉加减 
	for (Token::iterator iter = tokens.begin(); iter != tokens.end(); iter++) {
		
		if (*iter == "+") {
			
			___sint32 left = 0, right = 0, ret = 0;
			
			
			left = string_to_typex<___sint32>(*(iter - 1));
			right = string_to_typex<___sint32>(*(iter + 1));
			ret = left + right;
			
			iter = tokens.erase(iter - 1);
			iter = tokens.erase(iter);
			*iter = std::to_string(ret);
			
		} else if (*iter == "-") {
			
			___sint32 left = 0, right = 0, ret = 0;
			
			
			left = string_to_typex<___sint32>(*(iter - 1));
			right = string_to_typex<___sint32>(*(iter + 1));
			ret = left - right;
			
			iter = tokens.erase(iter - 1);
			iter = tokens.erase(iter);
			*iter = std::to_string(ret);
		}
	}
	
	return tokens;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值