HDU 1237 & WUSTOJ 1642 算术表达式的求值(简单+复杂)【栈和队列】

先说简单的算术表达式的求值
别慌,真正的算术表达式求值在后面,这只是前奏
题目来源:HDU http://acm.hdu.edu.cn/showproblem.php?pid=1237
在这里插入图片描述
★这题因为没有括号,所以很简单,甚至不需要栈和队列(我就没用)

相关知识:

算是小学知识了叭,一个规律不知道你们记得否:如果没有括号,算术表达式一定是一个数一个运算符交替排列的。

思路:

首先输入一个数,然后接着一定是 一个符号+一个数 的规律直到最后,在过程中,如果有乘除就运算,有减就把数变为相反数,有加就跳到下一个数开始。最后肯定都是加号,把所有数加起来即为答案。

代码:

#include<stdio.h>
#include<string.h>
int main()
{
     double num[200];
     int t;
     while(~scanf("%d",&t))
     {
         char c;
         int l=0,i;
         double sum=t*1.0;
         if(t==0&&(c=getchar())=='\n') return 0;
         while((c=getchar())!='\n')
         {
             if(c=='*') {scanf("%d",&t); sum*=t;}
             else if (c=='/') {scanf("%d",&t); sum/=t;}
             else if (c=='+') {scanf("%d",&t); num[l++]=sum; sum=t*1.0;}
             else if (c=='-') {scanf("%d",&t); num[l++]=sum; sum=-t*1.0;}
         }
         num[l++]=sum;
         double ans=0;
         for(i=0;i<=l-1;i++) ans+=num[i];
         printf("%.2lf\n",ans);
     }
}

是不是这题的一股清流233
话不多说,接下来是重头戏
题目来源:WUSTOJ http://acm.wust.edu.cn/problem.php?id=1642&soj=0
在这里插入图片描述
★因为有括号,所以再也没有那种骚操作 的规律了,老老实实用栈写(至少我不会其他操作了

相关知识:

首先 括号优先级最高,乘除其次,加减最低,废话
然后要知道,左括号绝大多数都在运算符右边(或者第一个字符就是左括号)

最后你要会把字符串里面的数准确的取出,这也是一个难点
话不多说,看我表演,show time~

思路:

定义两个栈,sign存放字符,num存放数。先读字符串,然后从头开始循环遍历每个字符。如果是+,把1压入sign;如果是-,把2压入sign;如果是*,把3压入sign;如果是/,把4压入sign;如果是(,把0压入sign;如果是数字,把它压入num(并不是简单的直接压,我只是简略的说 ),然后如果sign不为空,并且下一个字符不为数字(如果是数字,说明当前正在读取的数没有读完,好好理解这里),这时去sign栈顶,如果是* /,进行sum1运算,是-,进行sum2运算;如果是),就一直运算到sign栈顶为(,并把(给弹出,还没完,此时可能需要进行sum1,sum2运算。最后应该还会剩下一些数,但是符号一定只剩下+了,把他们简单的处理掉~最后答案就是num栈顶。
上面是较详细解读我的代码,从总体看,我的代码分为3步。解决();解决 / -;解决+*

注意:

别忘了,最后还保留了一个num没有弹出,把它处理一下。

代码:

#include<bits/stdc++.h>
using namespace std;
stack<int> sign;
stack<int> num;     //双栈
void sum1(int a)    //乘除法
{
    int x=num.top(); num.pop();
    int y=num.top(); num.pop();
    if(a==3) y=y*x;
    if(a==4) y=y/x;
    num.push(y);
    sign.pop();
}
void sum2()              //变为相反数
{
    int x=num.top(); num.pop();
    x=-x;
    sign.pop();
    num.push(x);
    sign.push(1);
}
int main()
{
    string s;
    while(cin>>s){
        int len=s.length();
        while(sign.size()) sign.pop();        //清空栈,这是我注意事项里面的操作
        while(num.size()) num.pop();
        for(int i=0;i<len;i++){
            if(s[i]>='0'&&s[i]<='9'){
                if(i&&s[i-1]>='0'&&s[i-1]<='9'){        
                    int a=num.top();
                    num.pop();
                    a=a*10+s[i]-'0';
                    num.push(a);
                }
                else num.push(s[i]-'0');                //完整取出数
                if(sign.size()){
                    if(i==len-1||((i<len-1)&&(s[i+1]<'0'||s[i+1]>'9'))){
                         int a=sign.top();
                         if(a==3||a==4)  sum1(a);
                         else if(a==2)  sum2();
                    }
                }
            }
            else if(s[i]=='+') sign.push(1);
            else if(s[i]=='-') sign.push(2);
            else if(s[i]=='*') sign.push(3);
            else if(s[i]=='/') sign.push(4);
            else if(s[i]=='('){
                sign.push(0);
                if(s[i+1]=='-') num.push(0);          //如果括号下一个字符是-,则多补一个0,可能没有这种情况---》 (-1)   但是万一有呢?
            }
            else if(s[i]==')'){
                int a=sign.top();
                while(a){
                    int x=num.top(); num.pop();
                    int y=num.top(); num.pop();
                    if(a==1) y=y+x;
                    num.push(y);
                    sign.pop();
                    a=sign.top();
                }
                sign.pop();
                if(sign.size()){
                    a=sign.top();
                    if(a==3||a==4)  sum1(a);
                    else if(a==2)   sum2();
                    else continue;
                }
            }
        }
        while(num.size()>1){
            int a=sign.top();
            sign.pop();
            int x=num.top(); num.pop();
            int y=num.top(); num.pop();
            if(a==1) y=y+x;
            num.push(y);
        }
        cout<<num.top()<<endl;
    }
}

我觉得我的代码很简单了,我看别人好多都是100+,我才80多行 。当然,人外有人,大佬看到就见笑了233.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值