扩大
缩小
halo!我是Pleiades_Antares,一个可爱的小姑娘~如果想了解更多请点击下方置顶自我介绍❤️
/*适应手机*/

表达式求值

表达式求值

文/Pleiades_Antares

原文是今年三月份写的,现在看简直不堪回首qwq但还是决定放出来,因为感觉其中一部分内容还是可以给各位一定启发的

(因为最后一小段是我【私以为】“原创”的hhh)目前最新的此题相关请看国庆PJ心得一文

以一个NOIP小辣鸡选手的身份来写的。

这里用的是洛谷的一道题,戳我查看洛谷本题目,(虽然我的答案不是洛谷AC代码,这个是给学弟学妹讲表达式求值基础的时候用的程序qvq)

(至于我为什么最近不写TG相关只写最基础的PJ的内容,请戳这里了解

这里提到前缀表达式&中缀表达式&后缀表达式的基础

首先是中缀表达式的c++程序,需要注意本程序只局限于一位数!!(改良版很容易鸭重点是理解题目)

附上代码与详解

//中缀表达式求值,only one digit!!
//感谢假牙! (假牙=我的计算机偶像quq)
#include<iostream>
#include<stack>
#include<cstring>
using namespace std;
stack<int> opnd;//数栈 
stack<char> optr;//符号栈 
string s;//字符串 
char pri[9][9]{">><<<<>>",">><<<<>>",">>>><<>>",">>>><<>>",">>>>><>>","<<<<<<= ","        ","<<<<<< ="};//优先级 
int dth(char a){
 if(a=='+') return 0;
 if(a=='-') return 1;
 if(a=='*') return 2;
 if(a=='/') return 3;
 if(a=='^') return 4;
 if(a=='(') return 5;
 if(a==')') return 6;
 if(a=='\0') return 7;
}
int cal(int n1,char tr,int n2){//计算的具体方法 
 if(tr=='+') return n1+n2;
 if(tr=='-') return n1-n2;
 if(tr=='*') return n1*n2;
 if(tr=='/') return n1/n2;
 if(tr=='^'){
  int ans=1;
  for(int i=0;i<n2;i++) ans*=n1;
  return ans;
 }
}
int main(){
    optr.push('\0');//最开始的符号 
     int i=0;
     cin>>s;//输入的数 
     while(!optr.empty()){//当符号栈不为空 
          char c=s[i];
          if(isdigit(c)){//假如是数 
               opnd.push(c-'0');//入数栈 
               i++;
          }
          else{//假如是符号 
               char cmp=pri[dth(optr.top())][dth(c)];//读取优先级数组 
               if(cmp=='<'){
            optr.push(c);
            i++;
               }
               else if(cmp=='='){
                optr.pop();
                i++;
               }
               else if(cmp=='>'){
                int n2=opnd.top();
                opnd.pop();
                int n1=opnd.top();
                opnd.pop();
                int result=cal(n1,optr.top(),n2);
                opnd.push(result);
                optr.pop();
               }
          }
     }
     cout<<opnd.top();
     return 0;
}     

中缀表达式比较慢,我们还可以来看看后缀表达式——计算机偏爱的语言。

警告
警告
警告
警告
以下内容由聪明机智善良的stellar原创,未经许可不得抄袭(虽然也没啥···)【???画风迷死】

话不多说,上家伙!

#include<iostream>
#include<cstring>
#include<stack>
//demi myself!
using namespace std;
char a[105];
stack<int> opnd;
int cal(int n1,char y,int n2){
    if (y=='+') return n1+n2;
    if (y=='-') return n1-n2;
    if (y=='*') return n1*n2;
    if (y=='/') return n1/n2;
}
int main(){
    cin>>a;
    int l=strlen(a);
    for(int i=0;i<l;i++){
        if (a[i]>='0'&&a[i]<='9'){
            opnd.push(a[i]-'0');
        }
        else{
            int n2=opnd.top();
            opnd.pop();
            int n1=opnd.top();
            opnd.pop();
            int ans=cal(n1,a[i],n2);
            opnd.push(ans);
        }
    }
    cout<<opnd.top()<<endl;
    return 0;
}

学会了后缀表达式,前缀表达式简直就是小case啦!

与后缀表达式一样,只不过是把原来扫法的倒过来扫了一遍而已

当然撒,也是stellar原创哦,别忘了标明原创xia(哦我的天哪我当时在想什么qwq)

上代码

#include<iostream>
#include<cstring>
#include<stack>
//demi myself!
using namespace std;
char a[105];
stack<int> opnd;
int cal(int n1,char y,int n2){
    if (y=='+') return n1+n2;
    if (y=='-') return n1-n2;
    if (y=='*') return n1*n2;
    if (y=='/') return n1/n2;
}
int main(){
    cin>>a;
    int l=strlen(a);
    for(int i=l-1;i>=0;i--){
        if (a[i]>='0'&&a[i]<='9'){
            opnd.push(a[i]-'0');
        }
        else{
            int n1=opnd.top();
            opnd.pop();
            int n2=opnd.top();
            opnd.pop();
            int ans=cal(n1,a[i],n2);
            opnd.push(ans);
        }
    }
    cout<<opnd.top()<<endl;
    return 0;
}

别忘了评论(*Φ皿Φ*)

posted @ 2018-10-01 20:50  Pleiades_Antares  阅读(168)  评论(0编辑  收藏  举报
levels of contents