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++表达式求值

"sharing?happiness is happy"

? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2021-10-8

一.细节处理:

1.注意负数 因此要进行字符串预处理

string format(string str) 
{
	int len = str.length();
	for (int i = 0; i < len; i++)
	{
		if (str[i] == '-')
		{
			if (i == 0) { str.insert(0, 1, '0'); }//处理-3*2+1情况
			else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//处理(-3*4+1)情况
		}
	}
	return str;
}

2.考虑除数为0

                    case '/':
					if (0 != y) { res = x / y; }
					else { cout << "非法表达式"; return -1; }
					break;

3.原字符串再加上一个定界符 '#'

str=str+'#'

4.优先级:? ?1."("未入栈前为3 入栈后为0 ??2.”)"和"#"为0? ? 3.”+" "-"为1? ? 4.”*"和"/"为2?

二.知识要点:

?中缀表达式转为后缀表达式

?1. 首先设置存储运算符和存储操作数两个栈? ? 即Symbol[N]和Num[N]且分别对应top2,top1

? ??

top1=-1 Symbol[0]='#' //运算符栈设置定界符 top2=0

?2.入栈和出栈的规则 字符串为str

? 一.若str[i]>='0&&str[i]<='9',则入操作数栈并继续扫描以一个字符 即Num[++top1]=str[i++]-'0';

? ?二.否则 将当前字符str1与运算符栈的栈顶元素str2进行优先级比较 ,自写比较函数

? ? ? 例如: str1==‘+’?则若str2==# ,(,) 则返回1 说明str1比str2优先级高

? ? ?1. 此时若str1优先级大于str2 则将str1入运算符栈并继续扫描 即 Symbol[++top2]=str[i++]

? ?? 2.优先级相等则返回0 此时将运算符栈顶元素弹出,并继续扫描下一个字符即 top2--? i++

? ? ?3.若str1优先级小于str2返回-1,此时将运算符栈顶元素弹出 即op=Symbol[top2--]

? ? ? ? 并弹出操作数栈的两个元素 即y=Num[top1--],x=Num[top1--]? 之后进行计算操作

? ?三.最后 return Num[top1]

三.完整源码:

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
class Expression
{
public:
	Expression(string str);
	~Expression();
	int Compute();
private:
	int Comp(char str1, char str2);
	string str1;
};
Expression::Expression(string str)
{
	this->str1 = str + '#';//以定界符开头
}
Expression :: ~Expression() {}
//将中缀表达转为后缀表达
int Expression::Compute()
{
	int Num[100], Symbol[100];//定义存操作数和运算符的两个栈
	int i, k, x, y, res;
	char op;
	Symbol[0] = '#';
	int top1 = -1, top2 = 0;
	for (i = 0; str1[i] != '\0';)
	{
		if (str1[i] >= '0' && str1[i] <= '9') { Num[++top1] = str1[i++] - '0'; }
		else {//非操作数就比较运算符优先级
			int cmp = Comp(str1[i], Symbol[top2]);
			if (cmp == 1) { Symbol[++top2] = str1[i++]; }//将运算符入栈 并接着扫描下一个字符
			else if (cmp == 0) { --top2; i++; }//优先级相等 弹栈 并接着扫描下一个字符
			else {//优先级低 继续处理当前运算符
				y = Num[top1--];//后面的数要先弹出来 才不会算反
				x= Num[top1--];
				op = Symbol[top2--];
				switch (op)
				{
				case '+':
					res = x + y;//将运算结果入栈
					break;
				case '-':
					res = x - y;
					break;
				case '*':
					res = x * y;
					break;
				case '/':
					if (0 != y) { res = x / y; }
					else { cout << "非法表达式"; return -1; }
					break;
				default:break;
				}
				Num[++top1] = res;
			}
		}
	}
	return Num[top1]; 
}
string format(string str) 
{
	int len = str.length();
	for (int i = 0; i < len; i++)
	{
		if (str[i] == '-')
		{
			if (i == 0) { str.insert(0, 1, '0'); }//处理-3*2+1情况
			else if (str[i - 1]=='(') { str.insert(i, 1, '0'); }//处理(-3*4+1)情况
		}
	}
	return str;
}
int main()
{
	string str;
	int n = 3;
	while (n--)
	{
		cout << "请输入一个表达式: " << endl;
		cin >> str;
		str = format(str);
		Expression E(str);
		int result = E.Compute();
		cout << "表达式的值的是: " << result << endl;
	}
	return 0;
}
int Expression::Comp(char str1, char str2)//当前字符元素和栈顶运算符优先级比较
{
	//1代表 str1优先级大于str2 0 代表相等 -1代表小于
	switch (str1)
	{
	case'+':case'-': 
		if (str2 == '#'||str2==')'||str2=='(') { return 1; }//左括号入队列后优先级变为0
		else { return -1; }
		break;
	case'*':case'/':
		if (str2 == '*' || str2 == '/') { return -1; }
		else  { return 1; }
		break;
	case'(':
		return 1;
		break;
	case')':
		if (str2 == '(') { return 0; }
		else if(str2 == '#') { return 1; }
		else { return -1; }
		break;
	case'#':
		if (str2 == '#') { return 0; }
		else { return -1; }
		break;
	default: break;
	}
}

四.测试结果:

?

五. 热爱编程 热爱计算机~

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:05:38  更:2021-10-09 16:06:18 
 
开发: 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年5日历 -2024/5/20 3:26:15-

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