IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 万能计算器——中缀表达式转换成后缀表达式(C++实现)【可以计算小数和负数】 -> 正文阅读

[C++知识库]万能计算器——中缀表达式转换成后缀表达式(C++实现)【可以计算小数和负数】

核心代码与思路:

int GetExprValue(vector<string> srcVec)   //根据后缀表达式求值
{
	stack<int> temp;
	char op = '\0';
	int a = 0;
	int b = 0;
	for (int i = 0; i < srcVec.size(); i++) {
		op = srcVec[i][srcVec[i].length() - 1];
		if (isdigit(op)) {
			temp.push(atoi(srcVec[i].c_str())); //如果是数字则直接入栈
		} else {
			a = temp.top();                     //否则从栈中取出两个操作数进行计算(注意操作数的左右顺序)
			temp.pop();							//然后将计算的值入栈
			b = temp.top();
			temp.pop();
			temp.push(CalFunc(b, op, a));
		}
	}
	return temp.top();
}

vector<string> GetSufix(string src)
{
	vector<string> dest;
	stack<char> opStack;
	int i = 0;
	string temp = "";
	while (i < src.length()) {
		if (isdigit(src[i])) {  //如果遇到数字就读取一个操作数加入后缀表达式中,注意是引用传递
			dest.push_back(ReadIntNum(src, i));
			i--; //由于后面会进行++操作,这里要保持在读到的最后一个数字位上
		} else if (IsLeftBrac(src[i])) { //如果遇到左括号直接入栈
			opStack.push(src[i]);
		} else if (IsRightBrac(src[i])) { //如果遇到右括号将栈顶元素出栈,加入后缀表达式,直到遇到左括号,将这个左括号弹出
			while (opStack.top()!= MatchBrac(src[i])) {
				temp += opStack.top();
				dest.push_back(temp);
				opStack.pop();
				temp = "";
			}
			opStack.pop(); //弹出( [ {
		} else if (IsOprand(src, i)){  //如果遇到的是操作符,将站定优先级大于等于该操作符的元素出栈,加入后缀表达式
			while ((!opStack.empty()) && (GetPri(opStack.top()) >= GetPri(src[i])) &&
					!IsLeftBrac(opStack.top())) {  //直到遇到左括号或栈为空(为空的判断优先)
				temp += opStack.top();
				dest.push_back(temp);
				opStack.pop();
				temp = "";
				
			}
			opStack.push(src[i]); //将当前字符入栈
		}
		
		i++;
	}
	while (!opStack.empty()) {
		temp += opStack.top();
		dest.push_back(temp);
		opStack.pop();
		temp = "";
	}

	return dest;
}

完整代码:

#include <iostream>
#include <vector>
#include <stack>
#include <cctype>
#include <cstdlib>
using namespace std;

bool IsLeftBrac(char ch)
{
	return (ch == '(' || ch == '[' || ch == '{');
}

bool IsRightBrac(char ch)
{
	return (ch == ')' || ch == ']' || ch == '}');
}

char MatchBrac(char ch)
{
	char temp;
	switch (ch) {
		case ')':
			temp = '(';
			break;
		case ']':
			temp = '[';
			break;
		case '}':
			temp = '{';
			break;
		default:
			temp = '\0';
			break;	
	}
	return temp;
}

bool IsOprand(string src, int idx)
{
	bool isSign = (src[idx] == '+' || src[idx] == '-' || src[idx] == '*' || src[idx] == '/');
	bool isValid = isdigit(src[idx - 1]) || IsRightBrac(src[idx - 1]); //运算符的左侧只能是数字或者右括号
	return (isSign && isValid);
}

string ReadIntNum(string src, int &idx)
{
	string value = "";
	if (src[idx - 1] == '-' && !IsOprand(src, idx - 1)){ //当数字的前一个是'-'且这个'-'不能作为运算符时就作为负号使用
			 value += '-';
	}
	while (isdigit(src[idx])) {
		value += src[idx++];
	}
	return value;
	
}

int CalFunc(int a, char op, int b)
{
	int ret = 0;
	switch (op) {
		case '+':
			ret = a + b;
			break;
		case '-':
			ret = a - b;
			break;
		case '*':
			ret = a * b;
			break;
		case '/':
			ret = a / b;
			break;
		default:
			ret = 0;
			break;
	}
	return ret;
}

int GetPri(char ch)
{
	int pri = 0;
	switch (ch) {
		case '+':
		case '-':
			pri = 1;
			break;
		case '*':
		case '/':
			pri = 2;
			break;
		default:
			pri = 0;
			break;
	}
	return pri;
}

int GetExprValue(vector<string> srcVec)   //根据后缀表达式求值
{
	stack<int> temp;
	char op = '\0';
	int a = 0;
	int b = 0;
	for (int i = 0; i < srcVec.size(); i++) {
		op = srcVec[i][srcVec[i].length() - 1];
		if (isdigit(op)) {
			temp.push(atoi(srcVec[i].c_str())); //如果是数字则直接入栈
		} else {
			a = temp.top();                     //否则从栈中取出两个操作数进行计算(注意操作数的左右顺序)
			temp.pop();							//然后将计算的值入栈
			b = temp.top();
			temp.pop();
			temp.push(CalFunc(b, op, a));
		}
	}
	return temp.top();
}

vector<string> GetSufix(string src)
{
	vector<string> dest;
	stack<char> opStack;
	int i = 0;
	string temp = "";
	while (i < src.length()) {
		if (isdigit(src[i])) {  //如果遇到数字就读取一个操作数加入后缀表达式中,注意是引用传递
			dest.push_back(ReadIntNum(src, i));
			i--; //由于后面会进行++操作,这里要保持在读到的最后一个数字位上
		} else if (IsLeftBrac(src[i])) { //如果遇到左括号直接入栈
			opStack.push(src[i]);
		} else if (IsRightBrac(src[i])) { //如果遇到右括号将栈顶元素出栈,加入后缀表达式,直到遇到左括号,将这个左括号弹出
			while (opStack.top()!= MatchBrac(src[i])) {
				temp += opStack.top();
				dest.push_back(temp);
				opStack.pop();
				temp = "";
			}
			opStack.pop(); //弹出( [ {
		} else if (IsOprand(src, i)){  //如果遇到的是操作符,将站定优先级大于等于该操作符的元素出栈,加入后缀表达式
			while ((!opStack.empty()) && (GetPri(opStack.top()) >= GetPri(src[i])) &&
					!IsLeftBrac(opStack.top())) {  //直到遇到左括号或栈为空(为空的判断优先)
				temp += opStack.top();
				dest.push_back(temp);
				opStack.pop();
				temp = "";
				
			}
			opStack.push(src[i]); //将当前字符入栈
		}
		
		i++;
	}
	while (!opStack.empty()) {
		temp += opStack.top();
		dest.push_back(temp);
		opStack.pop();
		temp = "";
	}

	return dest;
}

int main()
{
	string src;
	while (cin >> src) {
		vector<string> ret = GetSufix(src);
		cout << GetExprValue(ret) << endl;
	}
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-14 09:47:23  更:2022-05-14 09:48:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:14:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码