站外题求助
  • 板块灌水区
  • 楼主Justin_ding
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/12 22:32
  • 上次更新2024/7/13 09:29:10
查看原帖
站外题求助
1106222
Justin_ding楼主2024/7/12 22:32

小光正在学习如何写一个编译器,但是他的代码能力还不够。

他希望,编译器能够正确识别出带有括号的常数加、减、乘、幂算式,并且直接计算出算式的结果,以此达到编译优化的目的。现在,他把识别出的算式交给了你,你需要帮助他完成计算的任务。

算式的定义 为了严谨,我们将使用类似于上下文无关文法的规则来定义算式 ? S :

任意非负整数 ? ( ? ≥ 0 ) n(n≥0),是一个算式。例如:0, 123, 1905, 1145141918210 等。 如果 ? A 是一个算式, ? B 是一个算式, ? ? op 是 - 、+、* 和 ^ 中的一种,那么 ?

? ?

? A op B 拼接在一起,也是一个算式。例如:1+1, 53+1, 2^2^2 等。 如果 ? A 是一个算式,那么 ( ? ) (A) 也是一个算式。例如,(12), ((137)-(4+12)), (((1+1))) 等。 运算符说明 请注意,因为小光的机器只提供 32 位二进制寄存器,任何一个运算符的运算结果,超出二进制32位的进位和借位统统忽略,因此你需要输出运算结果在 32 位无符号整形中的值。

  • 运算符表示加法,例如 3+2 的结果是 5 ;4294967295+1 的结果是 0 (因为溢出)。加法满足结合律。
  • 运算符表示减法,例如 3-2 的结果是 1 ;0-1 的结果是 4294967295 (因为溢出)。减法不满足结合律,应当左结合优先运算,即 3-2-1 的结果是 ((3-2)-1)=0 而不是 (3-(2-1))=2 。
  • 运算符表示乘法,例如 3*2 的结果是 6 。乘法溢出相当于将结果 m o d     2 32 mod2 32 。乘法满足结合律。 ^ 运算法表示幂次运算,如果发生溢出相当于 m o d     2 32 mod2 32 ,即 a^b 的结果为 ? ? ( m o d 2 32 ) a b (mod2 32 ) 。在这里,幂次运算不满足结合律,且是一个右结合的运算符。即 2^3^4 = (2^(3^4)) 。特殊的,此题目中规定 0 0 的 0 0 次幂等于 1 1 。 算式的优先级中,幂次运算优先级最高,乘法次之,加法和减法的优先级相同且最低。而括号,则是最高优先级,最里层的括号运算应该最先计算。
#include<bits/stdc++.h>
using namespace std;
#define int unsigned int
string s;
int n;
stack<int> sti;
stack<char> stc;
int qpow(int x,int y){
    int ans=1;
    while(y){
        if(y&1)ans*=x;
        x*=x;y/=2;
    }
    return ans;
}
signed main(){
    cin>>s;
    s=" "+s;
    n=s.size()-1;
    for(int i=1;i<=n;i++){
        if(s[i]>='0'&&s[i]<='9'){
            int r=s[i]-'0';
            while(i+1<=n&&s[i+1]>='0'&&s[i+1]<='9'){
                r=r*10+s[i+1]-'0';i++;
            }
            sti.push(r);
        }else if(s[i]=='+'||s[i]=='-'){
            while(stc.size()&&(stc.top()=='*'||stc.top()=='^')){
                int x=sti.top();sti.pop();
                int y=sti.top();sti.pop();
                if(stc.top()=='*')sti.push(x*y);
                else sti.push(qpow(y,x));
                stc.pop();
            }
            stc.push(s[i]);
        }else if(s[i]=='*'){
            while(stc.size()&&stc.top()=='^'){
                int x=sti.top();sti.pop();
                int y=sti.top();sti.pop();
                sti.push(qpow(y,x));
                stc.pop();
            }
            stc.push(s[i]);
        }else if(s[i]==')'){
            while(stc.size()&&stc.top()!='('){
                int x=sti.top();sti.pop();
                int y=sti.top();sti.pop();
                if(stc.top()=='+'){
                    sti.push(x+y);
                }else if(stc.top()=='-'){
                    sti.push(y-x);
                }else if(stc.top()=='*')sti.push(x*y);
                else sti.push(qpow(y,x));
                stc.pop();
            }
            stc.pop();
        }else stc.push(s[i]);
    }
    while(sti.size()>1){
        int x=sti.top();sti.pop();
        int y=sti.top();sti.pop();
        if(stc.top()=='+'){
            sti.push(x+y);
        }else if(stc.top()=='-'){
            sti.push(y-x);
        }else if(stc.top()=='*')sti.push(x*y);
        else sti.push(qpow(y,x));
        stc.pop();
    }
    cout<<sti.top();
    return 0;
}

20pts QWQ

2024/7/12 22:32
加载中...