继上一篇扩展:文章: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;
}