zoukankan      html  css  js  c++  java
  • 计蒜客 表达式 (递归)


    **链接 : ** Here!

    **思路 : **

    • 这里采用一种非常风骚的写法, 对于求解表达式来说, 普通的做法就是用栈, 但是还可以利用递归来解决, 其实思考一下, 递归也是调用的系统栈, 所以说本质上并没有什么区别.

    • 首先, 设置优先级

      • "(", ")" 的优先级最高, 设置为100
      • "^" 的优先级次之, 设置为3
      • "*", "/" 的优先级再次之, 设置为2
      • "+", "-" 的优先级最低, 设置为1
    • 当传入一个字符串后, 给字符串中的所有运算符标记优先级等级, 然后选出来优先级最低的运算符, 因为优先级最低的运算符一定是最后计算, 因此就可以将一个表达式拆分成两个子表达式, 因此这就将大问题转化为等价的小问题, 递归解决即可

    • 这道题目中有变量 $a$ , 那么这该如何处理呢 ? 我们可以将 $a$ 替换为其他数字, 只要最后计算的结果相同就可以认为两个表达式是等价的,

    • 注意 :
      - 幂运算的数值可能非常大, 因此需要进行取模, 这里的 $MOD = 1e9 + 7$, 如果遇到乘法的话很可能超出 $int$ 的范围, 因此用 $longlong $ 来存储计算值.
      - 选用什么值来替换 $a$ 也是需要注意的一个地方.


    代码 :

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define INF 1e9
    typedef long long ll;
    const int MOD = 1e9 + 7;
    
    ll quick_pow(ll a, ll b) {
        ll ret = 1;
        while (b) {
            if (b & 1) ret = ret * a % MOD;
            a = a * a % MOD;
            b >>= 1;
        }
        return ret % MOD;
    }
    
    // [st, ed)
    ll cal_num(char *str, int st, int ed, int a) {
        int priority = 0;
        int opt_num = 0;
        int cur_priority = 0, min_priority = INF, min_pos = -1;
        for (int i = st ; i < ed ; ++i) {
            if (str[i] == '(') {priority += 100; continue;}
            else if (str[i] == ')') {priority -= 100; continue;}
            else if (str[i] == '+') cur_priority = priority + 1;
            else if (str[i] == '-') cur_priority = priority + 1;
            else if (str[i] == '*') cur_priority = priority + 2;
            else if (str[i] == '^') cur_priority = priority + 3;
            else continue;
            ++opt_num;
            if (cur_priority <= min_priority) {
                min_priority = cur_priority;
                min_pos = i;
            }
        }
        if (opt_num == 0) {
            ll temp = 0;
            for (int i = st ; i < ed ; ++i) {
                if (str[i] == 'a') return a;
                if (str[i] < '0' || str[i] > '9') continue;
                temp = temp * 10 + (str[i] - '0');
            }
            return temp % MOD;
        }
        ll ta = cal_num(str, st, min_pos, a);
        ll tb = cal_num(str, min_pos + 1, ed, a);
        switch (str[min_pos]) {
            case '+' :
                return (ta + tb) % MOD;
            case '-' :
                return (ta - tb + MOD) % MOD;
            case '*' :
                return (ta * tb) % MOD;
            case '^' :
                return quick_pow(ta, tb);
        }
        return 0;
    }
    
    #define MAX_RANGE 5
    int main() {
        // char s[100] =  "((1+2)*3) ^ a";
        // printf("%d
    ", cal_num(s, 0, strlen(s), 2));
        int rand_num[5] = {1, 2, 3, 4, 5};
        int n;
        char st[100], ed[100][100];
        while (scanf("%[^
    ]s", st) != EOF) {
            scanf("%d", &n);
            for (int i = 0 ; i < n ; ++i) {
                getchar();
                scanf("%[^
    ]s", ed[i]);
            }
            int vis[30] = {0}; // vis[i] = 0代表成功通过测试
            for (int i = 0 ; i < MAX_RANGE ; ++i) {
                int std_value = cal_num(st, 0, strlen(st), rand_num[i]);
                for (int j = 0 ; j < n ; ++j) {
                    if (vis[j]) continue;
                    int temp_value = cal_num(ed[j], 0, strlen(ed[j]), rand_num[i]);
                    if (temp_value != std_value) {
                        vis[j] = 1;
                    }
                }
            }
            for (int i = 0 ; i < n ; ++i) {
                if (vis[i]) continue;
                printf("%c", i + 'A');
            }
            printf("
    ");
            getchar();
        }
        return 0;
    }
    
  • 相关阅读:
    如何在Linux下的C++文件使用GDB调试
    21天学通C++(C++程序的组成部分)
    嵌入式Linux应用程序开发
    项目部署的问题
    未解决
    报错
    随笔
    逆向工程出现的错误1
    jpa学习
    springmvc整合mybaits
  • 原文地址:https://www.cnblogs.com/WArobot/p/7884468.html
Copyright © 2011-2022 走看看