C++表达式求值详解
更新时间:2021年10月9日 12:00 点击:1797
一.细节处理:
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; } }
四.测试结果:
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注猪先飞的更多内容!
相关文章
- vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
- 这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
- 取双引号内的内容我们如果一个字符串中只有一个可以使用explode来获得,但如果有多个需要使用正则表达式来提取了,具体的例子如下。 写程序的时候总结一点经验,如何只...2016-11-25
- 整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
- 这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同...2015-11-08
- 正则表达式是一门非常有用的并且进行模糊判断的一个功能了,我们下面来看通过正则来验证输入汉字、英语、数字,具体如下。 收藏了正则表达式。可以验证只能输入数...2016-11-25
- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
- 这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
- 本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
- 常用的日期时间正则表达式 下面收藏了大量的日期时间正则匹配函数,包括分钟,时间与秒都能达到。 正则表达式 (?n:^(?=d)((?<day>31(?!(.0?[2469]|11))|30(?!.0?2)|29(...2016-11-25
- 这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
- 网址规则是可寻的,所以我们可以使用正则表达式来提取字符串中的url地址了,下面一起来看看小编整理的几个PHP正则表达式匹配验证提取网址URL实例. 匹配网址 URL 的...2016-11-25
- 这篇文章主要介绍了C++ pair的用法实例详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了VSCode C++多文件编译的简单使用方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
- 虽然C++11引入了智能指针的,但是开发人员在与内存的斗争问题上并没有解放,如果我门实用不当仍然有内存泄漏问题,其中智能指针的循环引用缺陷是最大的问题。下面通过实例代码给大家介绍c++中的循环引用,一起看看吧...2020-04-25