《算法笔记》6.7小节 问题 A: 简单计算器

· · 个人记录

又是大模拟淦淦淦淦淦淦淦

思路:

这道题我居然用的队列orz。

言归正传,这道题就是模拟计算器。从读题目样例可以发现,数字的个数只比符号的个数多一个,那么这就给我们了思路:用队列,先提前放出一个数,每弹出一个字符,就处理两个数。

实现:

分三步

1.先把这输入的那一串序列分成两段,一段全是数字,一段全是字符。因为是输入一行,所以我们可以用到一个函数atoi(word.c_str()),将字符数字转化为数字,具体用法代码里。并且由于有空格,可以遇到空格就结束这一段输入的字符串,然后转化为数字,而符号过了必定是数字,符号只有一位,所以输入到+ - * /时,直接++循环函数,开始输入数字。

2.因为优先级,先处理 /。跟思路一样,先用一个last存储一开始的或者是运算完 /后需要留到下一次计算的,然后用另外一个变量存储当前到那个值了,把当前的符号判断,若是 /就计算,若不是,则直接把last存放进+ -计算的队列了,符号也是,把当前的变量赋值给last,进行下一次 /运算。

3.最后处理加减,这就简单了撒我就不说了。还是跟* /一样的思路, 跟上面的一样,我真不讲了(狗头)。

代码:

#include <bits/stdc++.h>
using namespace std;
queue<double> num;  //处理*/用 
queue<char> c;
queue<double> numm; //处理+-用 
queue<char> cc;
string x , word;
int main(){
    while(1){
        getline(cin , x);
        if(x == "0") break;
        while(!num.empty()) num.pop();  //多组数据需清空 
        while(!c.empty()) c.pop();
        while(!numm.empty()) numm.pop();
        while(!cc.empty()) cc.pop();
        word = "";
        for(int i = 0; i < x.size(); i++){
            if(x[i] != ' '){
                if(x[i] == '+' || x[i] == '-' || x[i] == '*' || x[i] == '/'){
                    c.push(x[i]);
                    i++;    //直接下一个,避免又一次空格 
                }else{
                    word += x[i];   //把这一位赋值给当前的数字 
                }
            }else{
                int n = atoi(word.c_str());
                num.push(n);
                word = "";
            }
            if(i == x.size() - 1){  //!!!!!这里需要注意一下,最后一个没有空格的,所以要特判 
                double n = atoi(word.c_str());  //内个string转int的函数,大概格式是这样的,word换成需要转化的字符就OK,其他不变 
                num.push(n);
                word = "";  //多余的 
            }
        }
        double a , last;
        char st;
        int len = num.size();   //!!!!!下面的循环的第二个不能用 num.size(),我就错了,因为num.size()一直在改变的,要重新弄一个 
        for(int i = 1; i <= len; i++){
            if(i == 1){ //因为数字数大于字符数,所以第一个提前取出 
                last = num.front();
                num.pop();
            }else{
                st = c.front() , a = num.front();
                c.pop() , num.pop();
                if(st == '*'){
                    last = last * a;
                }
                if(st == '/'){
                    last = last / a;
                }
                if(st == '+' || st == '-'){
                    numm.push(last);
                    last = a;
                    cc.push(st);
                }
                if(i == len) numm.push(last);   //同理,这里因为没有符号了,所以特判一下,加进去 
            }
        }
        double ans;
        len = numm.size();
        for(int i = 1; i <= len; i++){
            if(i == 1){
                ans = numm.front();
                numm.pop();
            }else{
                st = cc.front() , a = numm.front();
                cc.pop() , numm.pop();
                if(st == '+'){
                    ans += a;
                }else{
                    ans -= a;
                }
            }
        }
        printf("%.2f\n" , ans);
    }
    return 0;
}

吐槽:讲道理这道题不用栈就离谱。思路好想,比较考验编码能力吧。