基本计算器 IV

基本计算器 IV

给定一个表达式如 expression = "e + 8 - a + 5" 和一个求值映射,如 {"e": 1}(给定的形式为 evalvars = ["e"]evalints = [1]),返回表示简化表达式的标记列表,例如 ["-1*a","14"]

  • 表达式交替使用块和符号,每个块和符号之间有一个空格。
  • 块要么是括号中的表达式,要么是变量,要么是非负整数。
  • 变量是一个由小写字母组成的字符串(不包括数字)。请注意,变量可以是多个字母,并注意变量从不具有像 "2x""-x" 这样的前导系数或一元运算符 。

表达式按通常顺序进行求值:先是括号,然后求乘法,再计算加法和减法。

  • 例如,expression = "1 + 2 * 3" 的答案是 ["7"]

输出格式如下:

  • 对于系数非零的每个自变量项,我们按字典排序的顺序将自变量写在一个项中。

    • 例如,我们永远不会写像 “b*a*c” 这样的项,只写 “a*b*c”
  • 项的次数等于被乘的自变量的数目,并计算重复项。我们先写出答案的最大次数项,用字典顺序打破关系,此时忽略词的前导系数。

    • 例如,"a*a*b*c" 的次数为 4。
  • 项的前导系数直接放在左边,用星号将它与变量分隔开(如果存在的话)。前导系数 1 仍然要打印出来。

  • 格式良好的一个示例答案是 ["-2*a*a*a", "3*a*a*b", "3*b*b", "4*a", "5*c", "-6"]

  • 系数为

    0
    

    的项(包括常数项)不包括在内。

    • 例如,“0” 的表达式输出为 []

**注意:**你可以假设给定的表达式均有效。所有中间结果都在区间 [-231, 231 - 1] 内。

示例 1:

输入:expression = "e + 8 - a + 5", evalvars = ["e"], evalints = [1]
输出:["-1*a","14"]

示例 2:

输入:expression = "e - 8 + temperature - pressure",
evalvars = ["e", "temperature"], evalints = [1, 12]
输出:["-1*pressure","5"]

示例 3:

输入:expression = "(e + 8) * (e - 8)", evalvars = [], evalints = []
输出:["1*e*e","-64"]

提示:

  • 1 <= expression.length <= 250
  • expression 由小写英文字母,数字 '+', '-', '*', '(', ')', ' ' 组成
  • expression 不包含任何前空格或后空格
  • expression 中的所有符号都用一个空格隔开
  • 0 <= evalvars.length <= 100
  • 1 <= evalvars[i].length <= 20
  • evalvars[i] 由小写英文字母组成
  • evalints.length == evalvars.length
  • -100 <= evalints[i] <= 100

代码:

//模拟  多项式
class Solution {
public:
    class PloyCal{
    private:
        vector<int> coefs;
        vector<vector<string>> alphas;

    public:
        PloyCal(){ }
        PloyCal(int coef, string alpha){
            coefs.push_back(coef);
            alphas.emplace_back(vector<string>{alpha});
        }
        ~PloyCal(){ }

        PloyCal& operator+=(PloyCal& other){
            int n = other.coefs.size();
            for(int i = 0; i < n; i ++){
                this->add(other.coefs[i], other.alphas[i]);
            }
            return *this;
        }
        PloyCal& operator-=(PloyCal& other){
            int n = other.coefs.size();
            for(int i = 0; i < n; i ++){
                this->add(-other.coefs[i], other.alphas[i]);
            }
            return *this;
        }
        PloyCal& operator*=(PloyCal& other){
            PloyCal memo = *this;
            *this = PloyCal{};

            int n = other.coefs.size();
            for(int i = 0; i < n; i ++){
                PloyCal temp = memo;
                temp.mul(other.coefs[i], other.alphas[i]);
                (*this) += temp;
            }
            return *this;
        }

        // 减就是加-c
        void add(int c, vector<string>& a){
            if(c == 0) return;
            sort(a.begin(), a.end());
            for(int i = 0; i < alphas.size(); i ++){
                if(alphas[i] == a){
                    coefs[i] += c;
                    if(coefs[i] == 0){
                        coefs.erase(coefs.begin() + i);
                        alphas.erase(alphas.begin() + i);
                    }
                    return;
                }
            }

            coefs.push_back(c);
            alphas.push_back(a);
        }

        // 乘法
        void mul(int c, vector<string>& a){
            if(c == 0){
                coefs.clear();
                alphas.clear();
                return;
            }

            for(int i = 0; i < coefs.size(); i ++) coefs[i] *= c;
            if(a.size() && a[0].size()){
                for(auto& alpha: alphas){
                    if(alpha.size() && alpha.back().size() == 0) alpha.pop_back();
                    copy(a.begin(), a.end(), back_inserter(alpha));
                    sort(alpha.begin(), alpha.end());
                }
            }
        }

        vector<string> get_poly(){
            sort_poly();
            int n = coefs.size();
            vector<string> res;
            for(int i = 0; i < n; ++i){
                if(coefs[i] == 0) continue;
                string coef = to_string(coefs[i]);
                string alpha;
                for(string& s: alphas[i]){
                    if(alpha.size()) alpha += "*";
                    alpha += s;
                }
                if(alpha.size()) res.push_back(coef + "*" + alpha);
                else res.push_back(coef);
            }
            return res;
        }

        void sort_poly(){
            int n = coefs.size();
            vector<int> t(n);
            for(int i = 0; i < n; i ++) t[i] = i;
            for(int i = 0; i < n; i ++){
                while(alphas[i].size() && alphas[i].back().size() == 0) alphas[i].pop_back();
            }
            sort(t.begin(), t.end(), [this](int lhs, int rhs){
                int len1 = alphas[lhs].size(), len2 = alphas[rhs].size();
                if(len1 != len2) {
                    return len1 > len2;
                }
                return alphas[lhs] < alphas[rhs];
            });
            vector<int> sort_coefs(n);
            vector<vector<string>> sort_alphas(n);
            for(int i = 0; i < n; i ++){
                sort_coefs[i] = coefs[t[i]];
                sort_alphas[i] = alphas[t[i]];
            }
            coefs = sort_coefs;
            alphas = sort_alphas;
        }

        void show(){
            puts("current poly is:");
            for(int i = 0; i < coefs.size(); i ++){
                cout << coefs[i] << ":";
                for(string&s : alphas[i]) cout << s << "*";
                cout << endl;
            }
        }
    };

    vector<PloyCal> num;                        // 操作数
    vector<char> op;                            // 操作符

    // poly1 op poly2
    void cal(){
        int n = num.size();
        char cur_op = op.back();
        op.pop_back();

        if(cur_op == '+'){
            num[n-2] += num[n-1];
        }else if(cur_op == '-'){
            num[n-2] -= num[n-1];
        }else{
            num[n-2] *= num[n-1];
        }
        num.pop_back();
    }

    vector<string> basicCalculatorIV(string expr, vector<string>& var, vector<int>& var_num) {
        unordered_map<string, int> alpha2coef;
        for(int i = 0; i < var.size(); i ++) alpha2coef[var[i]] = var_num[i];

        int n = expr.size();
        int i = 0;
        while(i < n){
            if(expr[i] == ' ') {
                i ++;
                continue;
            }
            if(expr[i] == '(') {
                op.push_back('(');
                i ++;
                continue;
            }
            if(expr[i] == ')'){
                while(op.back() != '(') cal();
                op.pop_back();
                i ++;
                continue;
            }
            if(expr[i] == '+' || expr[i] == '-'){
                while(op.size() && op.back() != '(') cal();
                op.push_back(expr[i]);
                i ++;
                continue;
            }
            if(expr[i] == '*'){
                while(op.size() && op.back() == '*') cal();
                op.push_back(expr[i]);
                i ++;
                continue;
            }
            
            int space = i+1;
            while(space < n && expr[space] != ' ' && expr[space] != '(' && expr[space] != ')') space ++;
            
            // 生成新Poly
            int coef = 1;
            string alpha;

            // 操作数系数
            if(expr[i] < 'a') {
                coef = stoi(expr.substr(i, space-i));
            }
            // 操作数变量
            else {
                if(alpha2coef.count(expr.substr(i, space-i))){
                    coef = alpha2coef[expr.substr(i, space-i)];
                }else{
                    alpha = expr.substr(i, space-i);
                }
            }
            num.push_back(PloyCal{coef, alpha});
            i = space;
        }

        while(op.size()) cal();
        return num[0].get_poly();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值