在数据结构上遇到了这个题...但是觉得麻烦没写,想想还是要学的,特此记录下来。

以下是代码:

#include <Windows.h>
#include <iostream>
#include <vector>
#include <String>
#include <stack>
#include <cstdlib>
using namespace std;/*
第一步,转换成后缀表达式
第二部,利用后缀表达式求解如何转化为后缀表达式:顺序扫描中序表达式
a) 是数字, 直接输出
b) 是运算符
i : “(” 直接入栈
ii : “)” 将符号栈中的元素依次出栈并输出, 直到 “(“, “(“只出栈, 不输出
iii: 其他符号, 将符号栈中的元素依次出栈并输出, 直到 遇到比当前符号优先级更低的符号或者”(“。 将当前符号入栈。
扫描完后, 将栈中剩余符号依次输出*/
int main()
{string str_in;vector<string> houzhuibiaodashi;           //后缀表达式stack<char> CStack;string temp;            //临时stack <float> NStack;while (1){houzhuibiaodashi.clear();          //后缀表达式向量清空while (!CStack.empty())              //运算符栈清空{CStack.pop();}temp = "";                            //表达式清空while (!NStack.empty())              //数值栈清空{NStack.pop();}cout << "请输入多项式:";cin >> str_in;for (int i = 0; i < str_in.length(); i++){if (str_in[i] >= '0' && str_in[i] <= '9')            //处理数字{temp = str_in[i];while (str_in[i + 1] >= '0' && str_in[i + 1] <= '9' && i<str_in.length()){temp += str_in[++i];}houzhuibiaodashi.push_back(temp);              //数字推入后缀表达式}else if ((str_in[i] == '-' && i == 0) || (str_in[i] == '-'&& str_in[i - 1] == '('))       //处理负数,不能处理-(3+2)这种{temp = "";temp = str_in[i++];while (str_in[i] >= '0' && str_in[i] <= '9' && i<str_in.length()){temp += str_in[i];i++;}houzhuibiaodashi.push_back(temp);              //数字推入后缀表达式}if (str_in[i] == '(')       //小括号直接入运算符栈{CStack.push(str_in[i]);                //运算符入栈}else if (str_in[i] == ')'){temp = "";while (!CStack.empty() && CStack.top() != '('){temp = CStack.top();houzhuibiaodashi.push_back(temp);CStack.pop();}CStack.pop();         //(出栈}else if (str_in[i] == '+' || str_in[i] == '-' || str_in[i] == '*' || str_in[i] == '/'){temp = "";if (str_in[i] == '+' || str_in[i] == '-'){while (!CStack.empty() && (CStack.top() == '+' || CStack.top() == '-' || CStack.top() == '*' || CStack.top() == '/')){temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}CStack.push(str_in[i]);}else if (str_in[i] == '*' || str_in[i] == '/'){while (!CStack.empty() && (CStack.top() == '*' || CStack.top() == '/')){temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}CStack.push(str_in[i]);}}}while (!CStack.empty()){temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}/*完成后缀表达式,下边是李用后缀表达式求值*/int i = 0;float num1, num2;while (!houzhuibiaodashi.empty() && i<houzhuibiaodashi.size()){if (houzhuibiaodashi[i] == "+"){num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num1 + num2);}else if (houzhuibiaodashi[i] == "-"){if (i == 0)               //检测到负号时可能是负数{char * data = new char[houzhuibiaodashi.size()];for (int t = 1; t < houzhuibiaodashi[i].size(); t++){data[t] = houzhuibiaodashi[i][t];}NStack.push(0 - atoi(data));}else{num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num2 - num1);}}else if (houzhuibiaodashi[i] == "*"){num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num1 * num2);}else if (houzhuibiaodashi[i] == "/"){num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num1 / num2);}else{char * data = new char[houzhuibiaodashi.size()];for (int t = 0; t < houzhuibiaodashi[i].size(); t++){data[t] = houzhuibiaodashi[i][t];}NStack.push(atoi(data));}i++;}cout <<  "等式的值为" <<NStack.top() << endl;}system("pause");
}

更新后的代码:

#include <Windows.h>
#include <iostream>
#include <vector>
#include <String>
#include <stack>
#include <cstdlib>
using namespace std;
/*
第一步,转换成后缀表达式
第二部,利用后缀表达式求解
如何转化为后缀表达式:
顺序扫描中序表达式
a) 是数字, 直接输出
b) 是运算符
i : “(” 直接入栈
ii : “)” 将符号栈中的元素依次出栈并输出, 直到 “(“, “(“只出栈, 不输出
iii: 其他符号, 将符号栈中的元素依次出栈并输出, 直到 遇到比当前符号优先级更低的符号或者”(“。 将当前符号入栈。
扫描完后, 将栈中剩余符号依次输出
*/
int main()
{string str_in;vector<string> houzhuibiaodashi;           //后缀表达式stack<char> CStack;string temp;            //临时stack <float> NStack;while (1){houzhuibiaodashi.clear();          //后缀表达式向量清空while (!CStack.empty())              //运算符栈清空{CStack.pop();}temp = "";                            //表达式清空while (!NStack.empty())              //数值栈清空{NStack.pop();}cout << "请输入多项式:";cin >> str_in;for (int i = 0; i < str_in.length(); i++){if (str_in[i] == '(')        //小括号直接入运算符栈{CStack.push(str_in[i]);                //运算符入栈}else if (str_in[i] >= '0' && str_in[i] <= '9')          //处理数字{temp = str_in[i];while (str_in[i + 1] >= '0' && str_in[i + 1] <= '9' && i<str_in.length()){temp += str_in[++i];}houzhuibiaodashi.push_back(temp);              //数字推入后缀表达式}else if ((str_in[i] == '-'&&( i > 0 && !(str_in[i-1] >= '0' && str_in[i-1] <= '9'&& str_in[i + 1] >= '0' && str_in[i + 1] <= '9')) //排除num-num型减法&&( i > 0 && !(str_in[i - 1] == ')' && str_in[i + 1] >= '0' && str_in[i + 1] <= '9'))    //排除()-num型减法&&( i > 0 && !(str_in[i + 1] == ')' && str_in[i - 1] >= '0' && str_in[i - 1] <= '9')))   //排除num-()型减法|| (str_in[i] == '-'&& i == 0)                                     //加入负数在多项式开头的情况)//处理负数,不能处理-(3+2)这种{temp = "";temp = str_in[i++];while (str_in[i] >= '0' && str_in[i] <= '9' && i<str_in.length()){temp += str_in[i];i++;}houzhuibiaodashi.push_back(temp);              //数字推入后缀表达式i--;         //防止指针过度移动。上一个版本的下一个分支直接用了if,不是else if , 虽然能解决这个问题但是不严谨}else if (str_in[i] == '-'&& str_in[i + 1] == '(' && (i == 0))      //处理-(3+2)在开头的多项式{houzhuibiaodashi.push_back("-1");            //改成-1 * (5+2) 进行计算,先压入-1,之后按照*规则处理while (!CStack.empty() && (CStack.top() == '*' || CStack.top() == '/')){temp = "";temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}CStack.push('*');}else if (str_in[i] == ')'){temp = "";while (!CStack.empty() && CStack.top() != '('){temp = "";temp = CStack.top();houzhuibiaodashi.push_back(temp);CStack.pop();}CStack.pop();           //(出栈}else if (str_in[i] == '+' || str_in[i] == '-' || str_in[i] == '*' || str_in[i] == '/'){temp = "";if (str_in[i] == '+' || str_in[i] == '-'){while (!CStack.empty() && (CStack.top() == '+' || CStack.top() == '-' || CStack.top() == '*' || CStack.top() == '/')){temp = "";temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}CStack.push(str_in[i]);}else if (str_in[i] == '*' || str_in[i] == '/'){while (!CStack.empty() && (CStack.top() == '*' || CStack.top() == '/')){temp = "";temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}CStack.push(str_in[i]);}}}while (!CStack.empty()){temp = CStack.top();CStack.pop();houzhuibiaodashi.push_back(temp);}/*完成后缀表达式,下边是李用后缀表达式求值*/int i = 0;float num1, num2;while (!houzhuibiaodashi.empty() && i<houzhuibiaodashi.size()){if (houzhuibiaodashi[i] == "+"){num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num1 + num2);}else if (houzhuibiaodashi[i] == "-"){if (i == 0)             //检测到负号时可能是负数{char * data = new char[houzhuibiaodashi.size()];for (int t = 1; t < houzhuibiaodashi[i].size(); t++){data[t] = houzhuibiaodashi[i][t];}NStack.push(0 - atoi(data));}else{num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num2 - num1);}}else if (houzhuibiaodashi[i] == "*"){num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num1 * num2);}else if (houzhuibiaodashi[i] == "/"){num1 = NStack.top();NStack.pop();num2 = NStack.top();NStack.pop();NStack.push(num2 / num1);}else{char * data = new char[houzhuibiaodashi.size()];for (int t = 0; t < houzhuibiaodashi[i].size(); t++){data[t] = houzhuibiaodashi[i][t];}NStack.push(atoi(data));}i++;}cout <<  "等式的值为" <<NStack.top() << endl;}system("pause");
}

代码更新说明:

上一个版本(就是划线的)简直bug百出,不能计算-(5+2)这种,除号和减号的运算规则也有错误。本次更新内容:

进一步优化判断条件;

修复了一些操作符bug;

完美支持加减乘除操作。

可自行加入乘方或者其他运算操作

第一步是将中缀表达式转换成后缀表达式。这一步很麻烦,用到的转换规则不是很好理解:

  1. 建立符号栈
  2. 顺序扫描中序表达式 
    a) 是数字, 直接输出 (即压入后缀表达式)
    b) 是运算符 
    i : “(” 直接入栈 (压入运算符栈CStack)
    ii : “)” 将符号栈中的元素依次出栈并输出(压入后缀表达式), 直到 “(“, “(“只出栈, 不输出 
    iii: 其他符号, 将符号栈中的元素依次出栈并输出, 直到 遇到比当前符号优先级更低的符号或者”(“。 将当前符号入栈。
  3. 扫描完后, 将栈中剩余符号依次输出

iii解释一下:举个例子,如果当前运算符栈中的内容是+,而当前的运算符是-,因为+不符合“比当前符号优先级低”的条件,所以需要将+弹栈并压入后缀表达式。之后栈为空,可以将-压入。也就是说,如果当前操作符是+、-,则一直弹栈,直到栈为空或者遇到“(”。如果当前操作符是*、/,则一直弹栈直到遇到+-或者“(”。

第二步是根据后缀表达式求值。很简单,从头读取后缀表达式,数字则压入数字栈,遇到操作符则从数字栈弹出相应数量数字进行运算(注意减法的减数和被减数不能搞错),运算结果压入数字栈。 最终,数字栈将只剩下一个数字,即为多项式运算结果。

附运行截图:

欢迎大家批评指正。

C++ 直接计算多项式的值相关推荐

  1. 1.5 编程基础之循环控制 36 计算多项式的值 python

    http://noi.openjudge.cn/ch0105/36/ """ 1.5 编程基础之循环控制 36 计算多项式的值 http://noi.openjudge. ...

  2. 信息学奥赛一本通 1012:计算多项式的值 | OpenJudge NOI 1.3 07

    [题目链接] ybt 1012:计算多项式的值 OpenJudge NOI 1.3 07:计算多项式的值 [题目考点] 1. 计算表达式书写 了解*的运算优先级比+高. 了解()可以改变运算优先级 2 ...

  3. 信息学奥赛一本通(1093:计算多项式的值)

    1093:计算多项式的值 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 36753     通过数: 16786 [题目描述] 假定多项式的形式为xn+xn−1+ ...

  4. 信息学奥赛一本通(1012:计算多项式的值)

    1012:计算多项式的值 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 67156     通过数: 41769 [题目描述] 对于多项式f(x)=ax3+bx2 ...

  5. POJ NOI0105-36 计算多项式的值

    问题链接:POJ NOI0105-36 计算多项式的值. 总时间限制: 1000ms 内存限制: 65536kB 描述 假定多项式的形式为xn+xn-1+-+x2+x+1,请计算给定单精度浮点数x和正 ...

  6. 1093:计算多项式的值

    1093:计算多项式的值 时间限制: 1000 ms 内存限制: 65536 KB [题目描述] 假定多项式的形式为xn+xn−1+-+x2+x+1xn+xn−1+-+x2+x+1,请计算给定单精度浮 ...

  7. 东华OJ第85题 计算多项式的值

    85 计算多项式的值 作者: Turbo时间限制: 1S章节: 循环 问题描述 : 计算并输出当x<0.97时下列多项式的值,直到最后一项的绝对值小于threshold(该项不包括在多项式的结果 ...

  8. 计算多项式的值——基于C语言程序

    方法一:直接法 计算多项式的值最容易想到的方法就是直接法,直接把多项式的每一项相加起来. double f2(int n , double a[] , double x){int i;double p ...

  9. 信息学奥赛一本通——1012:计算多项式的值

    大家好 今天给大家带来<信息学奥赛一本通--1012:计算多项式的值> 看题目: 1012:计算多项式的值 时间限制: 1000 ms         内存限制: 65536 KB 提交数 ...

  10. 第 n 小的质数 与 7 无关的数 计算多项式的值 三道水题(深学思维)

    前言: 额此篇没有前言太水了 First.第 n 小的质数 输入一个正整数 n, 求正整数范围中第 n 小的质数. 输入描述 一个不超过 30000 的正整数 n. 输出描述 第 n 小的质数. 用例 ...

最新文章

  1. 技术大佬们都推荐的vim学习指南来了,值得收藏!
  2. 推荐系统数据集大列表
  3. 展讯camera去除尺寸相关缓存
  4. hdmi 屏幕旋转 树莓派_计算机实验室之树莓派:课程 9 屏幕04
  5. 互动赠新书|当云原生遇到混合云:如何实现“求变”与“求稳”的平衡
  6. 用SSD训练自己的数据集
  7. Vue eslint 团队代码规范
  8. Halcon学习笔记——机器视觉应用工程开发思路及相机标定
  9. 6大设计原则之里氏替换原则
  10. 别想了:全系iPhone12将不配120Hz高刷屏
  11. WSUS补丁服务器部署详细 利用WSUS部署更新程序
  12. 2015-2020年各类国际会议与期刊基于图像的三维对象重建论文综述(2)——Encoder stage
  13. 考驾照科目一考试很顺利
  14. 拓端tecdat|R语言线性判别分析(LDA),二次判别分析(QDA)和正则判别分析(RDA)
  15. (二)Easyexcel 的使用(读取数据到map集合中)
  16. veracrypt加密mysql_VeraCrypt怎么用 VeraCrypt加密文件的图文教程方法
  17. 转转验机源码+后台管理
  18. JOIN连接:LEFT OUTER JOIN
  19. mysql是怎么实现多对多的_mysql复习篇及一对多和多对多的总结(17.6.26 )
  20. 嵌入式开发板硬件操作入门学习9——集成电路芯片手册术语词汇表(中英文对照)

热门文章

  1. 分析一个简单的汇编代码
  2. Dell B1260dn Printer驱动的安装
  3. Python爬虫入门实战2:获取CSDN个人博客文章基础信息
  4. python做乘法运算定律_《乘法运算定律》(一)教学设计
  5. 使android桌面图标变大
  6. golang开发环境之Sublime Text 2+GoSublime+gocode+MarGo
  7. 云计算简介:云计算定义、云计算优势、云计算分类、云计算历史
  8. PT100(RTD)三线制四线制测量方案
  9. 计算机系统原理实验——微程序控制器
  10. 统计学基于matlab,MATPLOT:一款基于MATLAB的地球化学数据分析成图软件