string数学表达式处理

优化一下上次写的代码,加上了注释,加强了可读性和封装性

#include "reverse_polish.h"
void reverse_polish()
{
	string st;
	cout << "输入一个表达式" << endl;
	cin >> st;
	cout<<main_logic(st);
}
//处理括号
string main_logic(string &st)
{
	if (0 == check_parentheses(st))
	{
		return calculate(st);
	}
	else
	{
		string start = "", mid = "", end = "";//将字符串分割成第一个正括号前面,第一个反括号后面,还有中间,中间的递归
		ite mid_s, mid_e, temp;
		mid_e = find_end(st);
		mid_s = find_start(st);
		if (mid_s != st.begin())
		{
			start = get_start(st,mid_s);
		}
		if (mid_s != mid_e)
		{
			mid = get_mid(mid_s, mid_e);
		}
		if (mid_e != st.end())
		{
			end = get_end(st, mid_e);
		}
		return main_logic(start + main_logic(mid) + end);
	}
}
//获取第一个反括号前面的第一个正括号
ite find_start(string &st)
{
	auto it = st.begin();
	while (it != st.end())
	{
		if (*it == ')')
		{
			while (it != st.begin())
			{
				if (*it == '(')
				{
					return it;
				}
				--it;
			}
		}
		++it;
	}
	return it;
}
//获取第一个反括号
ite find_end(string &st)
{
	auto it = st.begin();
	while (it != st.end())
	{
		if (*it == ')')
		{
			break;
		}
		++it;
	}
	return it;
}
//获取括号前面的字符串
string get_start(string &st, ite it)
{
	string start;
	ite temp = st.begin();
	while (temp != it)
	{
		start += *temp;
		++temp;
	}
	return start;
}
//获取括号里面的字符串
string get_mid(ite start, ite end)
{
	string mid;
	ite temp;
	temp = start + 1;
	while (temp != end)
	{
		mid += *temp;
		++temp;
	}
	return mid;
}
//获取括号后面的字符串
string get_end(string &st, ite it)
{
	string end;
	ite temp;
	temp = it + 1;
	while (temp != st.end())
	{
		end += *temp;
		++temp;
	}
	return end;
}
//检查括号
int check_parentheses(string &st)
{
	int count = 0;
	for (auto it : st)
	{
		if (it == '(')
		{
			++count;
		}
	}
	return count;
}

//处理不带括号的表达式分解成第一个操作数前面和2个操作数和操作符还有第二个操作数后面的一共3个字符串
string calculate(string &st)
{
	if (0 == check_high(st))
	{
		return calculate_low(st);
	}
	else
	{
		string start = "", mid = "", end = "", temp = "";//处理字符串中的高阶乘除法
		ite start_m, end_m, point;
		end_m = find_calculate_end(st);
		start_m = find_calculate_start(st);
		if (start_m != st.begin())
		{
			start = get_calculate_start(st, start_m);
		}
		if (end_m != st.end() - 1)
		{
			end = get_calculate_end(st, end_m);
		}
		mid = get_calculate_mid(start_m + (start_m != st.begin()), end_m);
		return calculate(start + calculate_high(mid) + end);
	}
}
//获取第二个操作数后面的符号位置
ite find_calculate_end(string &st)
{
	ite it = st.begin(), point;
	while (*it != '*'&&*it != '/')
	{
		++it;
	}
	point = it + 1;
	while (point != st.end())
	{
		if (*point == '+' || *point == '-' || *point == '*' || *point == '/')
		{
			if (point != it + 1)
			{
				break;
			}
		}
		++point;
	}
	return point;
}
//获取第一个操作数前面的符号位置
ite find_calculate_start(string &st)
{
	ite it = st.begin(), point;
	while (*it != '*'&&*it != '/')
	{
		++it;
	}
	point = it;
	while (point != st.begin())
	{
		if (*point == '+' || *point == '-'&&*(point - 1) != '+'&&*(point - 1) != '-')
		{
			break;
		}
		--point;
	}
	return point;
}
//获取无括号表达式的第一个操作数前面的字符串
string get_calculate_start(string &st, ite it)
{
	string start;
	ite point;
	point = st.begin();
	while (point != it + 1)
	{
		start += *point;
		++point;
	}
	return start;
}
//获取第二个操作数后面的的字符串
string get_calculate_end(string &st, ite it)
{
	string end;
	ite point;
	point = it;
	while (point != st.end())
	{
		end += *point;
		++point;
	}
	return end;
}
//获取2个操作数和操作符的字符串
string get_calculate_mid(ite start, ite end)
{
	string mid;
	ite point = start;
	while (point != end)
	{
		mid += *point;
		++point;
	}
	return mid;
}
//计算高阶计算*和/
string calculate_high(string &st)
{
	int count = 0;
	auto it = st.begin();
	double total = atof(st.c_str());
	string temp;
	while (*it != '*'&&*it != '/')
	{
		++count;
		++it;
	}
	if (*it == '*')
	{
		total *= atof(st.c_str() + count + 1);
	}
	else
	{
		total /= atof(st.c_str() + count + 1);
	}
	temp = to_string(total);
	return temp;
}
//检查高阶运算符数量
int check_high(string &st)
{
	int count = 0;
	for (auto it : st)
	{
		if (it == '*' || '/' == it)
		{
			++count;
		}
	}
	return count;
}
//计算低阶运算符数量,不会把第一个数的负号当成操作符
int check_low(string &st)
{
	int count = 0;
	auto it = st.begin();
	if (*it == '+' || *it == '-')
	{
		++it;
	}
	for (; it != st.end(); ++it)
	{
		if (*it == '+' || '-' == *it)
		{
			++count;
		}
	}
	return count;
}
//计算低阶计算+和-
string calculate_low(string &st)
{
	if (0 == check_low(st))
	{
		return st;
	}
	else
	{
		string first, next;
		ite point = find_calculate_low_point(st);
		first = get_low_first(st, point);
		next = get_low_next(st, point);
		return calculate_low(calculate_add(first) + next);
	}
}
//分解得到2个操作数和一个操作符的字符串
string get_low_first(string &st, ite it)
{
	string first;
	ite point = st.begin();
	while (point != it)
	{
		first += *point;
		++point;
	}
	return first;
}
//第二个操作数后面的字符串
string get_low_next(string &st, ite it)
{
	string next;
	ite point = it;
	while (point != st.end())
	{
		next += *point;
		++point;
	}
	return next;
}
//寻找第二个低阶运算操作数后面的位置,可以是字符串结尾
ite find_calculate_low_point(string &st)
{
	ite it = st.begin();
	if (*it == '-' || *it == '+')
	{
		if (*(it + 1) != '+'&&*(it + 1) != '-')
		{
			++it;
		}
	}
	while (*it != '+' && *it != '-')
	{
		++it;
	}
	while (*it < '0' || *it > '9')
	{
		++it;
	}
	while (*it != '+' && *it != '-')
	{
		++it;
		if (it == st.end())
		{
			break;
		}
	}
	return it;
}
//计算低阶运算
string calculate_add(string &st)
{
	double total = atof(st.c_str());
	int count = 0;
	ite it = st.begin();
	if (*it == '-' || *it == '+')
	{
		if (*(it + 1) != '+'&&*(it + 1) != '-')
		{
			++count;
			++it;
		}
	}
	while (*it != '+' && *it != '-')
	{
		++count;
		++it;
	}
	if (*it == '+')
	{
		total += atof(st.c_str() + count + 1);
	}
	else
	{
		total -= atof(st.c_str() + count + 1);
	}
	return to_string(total);
}
主函数和头文件
#include "reverse_polish.h"
int main()
{
	reverse_polish();
	system("pause");
	return 0;
}

#include <iostream>
#include <string>
#include <stack>
#include <iterator>
using namespace std;
typedef std::_String_iterator<std::_String_val<std::_Simple_types<char>>> ite;
//获取数学表达式字符串
void reverse_polish();
/*处理括号------------------------------------*/
string main_logic(string &st);
//获取第一个反括号前面的第一个正括号
ite find_start(string &st);
//获取第一个反括号
ite find_end(string &st);
//获取括号前面的字符串
string get_start(string &st, ite it);
//获取括号里面的字符串
string get_mid(ite start, ite end);
//获取括号后面的字符串
string get_end(string &st, ite it);
//检查括号个数
int check_parentheses(string &st);
/*括号处理完毕--------------------------------*/

//处理不带括号的表达式分解成第一个操作数前面和2个操作数和操作符还有第二个操作数后面的一共3个字符串
string calculate(string &st);
//获取第二个操作数后面的符号位置
ite find_calculate_end(string &st);
//获取第一个操作数前面的符号位置
ite find_calculate_start(string &st);
//获取无括号表达式的第一个操作数前面的字符串
string get_calculate_start(string &st,ite it);
//获取第二个操作数后面的的字符串
string get_calculate_end(string &st, ite it);
//获取2个操作数和操作符的字符串
string get_calculate_mid(ite start,ite end);
//计算高阶计算*和/
string calculate_high(string &st);
//检查高阶运算符数量
int check_high(string &st);
//计算低阶计算+和-
string calculate_low(string &st);
//寻找第二个低阶运算操作数后面的位置,可以是字符串结尾
ite find_calculate_low_point(string &st);
//计算低阶运算符数量,不会把第一个数的负号当成操作符
int check_low(string &st);
//分解得到2个操作数和一个操作符的字符串
string get_low_first(string &st, ite it);
//第二个操作数后面的字符串
string get_low_next(string &st, ite it);
//计算低阶运算
string calculate_add(string &st);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值