中缀试转后缀试及前缀试并计算其结果

简介:

/*
        参考大神nb的代码,感觉思路不错!终于搞明白了!一开始不明白在计算表达式的时候,利用栈到底做了什么!现在感觉我们利用栈就是模拟我们书面上计算表达式,
       将优先级高的运算先计算出来,然后放进栈中,等待下一次的计算
*/
#include<iostream> 
#include<string> 
#include<stack>
#include<cstdio>
using namespace std;

class node
{
public:
     double ret;
     string prefix, suffix;//前缀表达式和后缀表达式 
     node()
     {
         ret=0;
         prefix=suffix=""; 
     } 
};

stack<node>optd;//操作数栈
stack<char>optr;//操作符栈

char formula[1000];//表达式以"=" 结束 

int cmp(char ch)//定义符号的优先级
{
   switch(ch)
   {
      case '#': return -2;
      case '=': return -1;
      case '+':
      case '-': return 1;
      case '*':
      case '/': return 2;
      case '(': return 3;
      case ')': return 0;
   }
   return -2;
}

double deal(double x, char ch, double y)
{
   switch(ch)
   {
       case '+': return x+y;
       case '-': return x-y;
       case '*': return x*y;
       case '/': return x/y;
   }
   return 0.0;
}

void cal()
{
   int i=0, n;
   node num, aTmp, bTmp;
   while(optr.top()!='=')
   {
      if(formula[i]>='0' && formula[i]<='9')
      {
           sscanf(formula+i, "%lf%n", &num.ret, &n);
           num.prefix.assign(formula+i, n);
           num.suffix.assign(formula+i, n);
           i+=n;
           optd.push(num);
      }
      else
      {
           if(optr.top()=='(' && formula[i]==')')//消除一对括弧 
           {
         optr.pop();
         ++i;
         }
           if(cmp(formula[i]) > cmp(optr.top()) || optr.top()=='(')//当前运算符大于栈顶运算符直接进栈
     {
         optr.push(formula[i]);
         ++i;
     }
     else
     {
        char ch=optr.top(), preTmp[]={ch, ' ', '\0'}, sufTmp[]={' ', ch, '\0'} ;
        optr.pop();//弹出一个栈顶操作符 
        bTmp=optd.top(); optd.pop();//得到第二个操作数 
        aTmp=optd.top(); optd.pop();//得到第一个操作数 
        aTmp.ret=deal(aTmp.ret, ch, bTmp.ret);
        
        aTmp.suffix+=" " + bTmp.suffix + sufTmp;//得到运算后的后缀式子
        aTmp.prefix=preTmp + aTmp.prefix + " " + bTmp.prefix;//得到运算前的后缀式子
        optd.push(aTmp);//不要忘记将计算的结果放入栈中 
     }
      }
   }
   optr.pop();//别忘记弹出栈顶上的'=' 
}

int main()
{
   optr.push('#');//初始化栈顶操作符是‘#’ 
   while(cin>>formula)
   {
       cal();
       node ans=optd.top(); optd.pop();
       cout<<"表达式结果:"<<ans.ret<<endl<<"前缀试:"<<ans.prefix+'='<<endl<<"后缀试:"<<ans.suffix+'='<<endl; 
   }
   return 0;
}

目录
相关文章
|
14天前
|
算法 测试技术 C#
【字典树】【字符串】【 前缀】100268. 最长公共后缀查询
【字典树】【字符串】【 前缀】100268. 最长公共后缀查询
|
3月前
|
编译器 C++
【C++14保姆级教程】数位分割符、函数返回值推导
【C++14保姆级教程】数位分割符、函数返回值推导
|
8月前
|
运维 Shell Python
【运维知识高级篇】超详细的Shell编程讲解2(变量切片+统计变量长度+字串删除+字串替换+七种方法进行数值运算+整数比较+多整数比较+文件判断+字符串比对+正则比对+配合三剑客的高阶用法)(一)
【运维知识高级篇】超详细的Shell编程讲解2(变量切片+统计变量长度+字串删除+字串替换+七种方法进行数值运算+整数比较+多整数比较+文件判断+字符串比对+正则比对+配合三剑客的高阶用法)
89 0
|
5月前
|
存储 Java 网络安全
用正则表达式匹配3的任意倍数
正则表达式能匹配3的任意倍数?(注意是任意倍数) ,我曾经也很震惊,但确实可以。我5年多前练习正则表达式,在Regex Golf这个正则表达式测试网站上发现了这个题,当时完全没有任何头绪,于是我在知乎提问正则表达式如何匹配 3 的倍数 ,但是得到了好多知乎大佬的关注,也上了当天的热榜。 排名第一的答主已经给出了答案和思路,但这么多年来我一直都没看懂,最近学习编译原理,看到正则表达式和DFA,于是仔细研究了一下这个问题,并将问题扩展至匹配N的倍数,最后给出通用解法和代码。
16 0
|
6月前
|
机器学习/深度学习 算法 测试技术
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例
C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例
|
8月前
|
运维 Shell Perl
【运维知识高级篇】超详细的Shell编程讲解2(变量切片+统计变量长度+字串删除+字串替换+七种方法进行数值运算+整数比较+多整数比较+文件判断+字符串比对+正则比对+配合三剑客的高阶用法)(二)
【运维知识高级篇】超详细的Shell编程讲解2(变量切片+统计变量长度+字串删除+字串替换+七种方法进行数值运算+整数比较+多整数比较+文件判断+字符串比对+正则比对+配合三剑客的高阶用法)(二)
92 0
|
9月前
中缀表达式转前缀或后缀并计算结果 2021-04-28
中缀表达式转前缀或后缀并计算结果 2021-04-28
【每日一题Day81】LC2185统计包含给定前缀的字符串 | 模拟
思路:判断每一个word是否以prefix开头,最后返回满足条件的单词数量。
48 0
|
C语言
c语言中各种进制的前缀后缀
c语言中各种进制的前缀后缀
288 0
AcWing 779. 最长公共字符串后缀
AcWing 779. 最长公共字符串后缀
82 0
AcWing 779. 最长公共字符串后缀

热门文章

最新文章