zoukankan      html  css  js  c++  java
  • 计算2*3+(2*(5+6)*3)/2+4*6的值

    代码弊端:

    1.初始公式串的数值只能是0-9. 大于10的数字会有问题,可以改造myCopy函数

    2. 计算顺序是从左到右。 比如2*3*4是先算的2*3 再算的rusult*4. 貌似c语言是从又到左的计算顺序

    #include<iostream>
    #include<iomanip>
    #include<vector>
    #include<algorithm>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    using namespace std;
    
    
    bool isOper(char val)
    {
        return ((val == '+') || (val == '-') ||(val == '*') || (val == '/') ||(val == '(') || (val == ')'));
    }
    
    //把char*字符串拷贝到vector中
    void myCopy(vector<char>& container, char* v)
    {
        while(*v != 0)
        {
            if (isOper(*v))
            {
                container.push_back(*v);
            }
            else
            {
                container.push_back(*v  - '0');
            }
            v++;
        }
    }
    
    void prtVecs(const vector<char>& values, const vector<int>& pris)
    {
        //打印权重串
        for(auto pri : pris)
        {
            cout << " " << pri;
        }
        cout << endl;
        //打印公式串
        for(auto val : values)
        {
            if (isOper(val))
            {
                cout << " " << val;
            }
            else
            {
                cout << " " << (int)val;
            }
        }
        cout << endl;
    }
    
    void prtVecs(const vector<char>& values)
    {
        //打印公式串
        for(auto val : values)
        {
            if (isOper(val))
            {
                cout << " " << val;
            }
            else
            {
                cout << " " << (int)val;
            }
        }
        cout << endl;
    }
    
    //加减乘除计算
    int realCal(int first, char oper, int second)
    {
        if (oper == '+') return first + second;
        if (oper == '-') return first - second;
        if (oper == '*') return first * second;
        if (oper == '/') return first / second;
        return -1;
    }
    
    /*权重计算:
    数字权重固定是0,()权重固定是-1;
    加减的基础权重是1 乘除的基础权重是2 ;
    ()括号控制附加权重0, (:附加权重+2 ):附加权重-2
    [之所以选择附加权重为2举例: 2*(2+3)中要先算加法. 加的基础权重1+附加权重2得到3;乘的基础权重2+附加权重0得到2.所以会先算加法]
    加减乘除的最终权重为 他的基础权重+当前附加权重*/
    
    //values公式串, pris公式串对应的权重串[in out]
    int calPri(const vector<char>& values, vector<int>& pris)
    {
        int basePri = 0; //附加权重
        for(int i = 0; i < values.size(); ++i)
        {
            if (!isOper(values[i]))
            {
                pris[i]  = 0;
            }
    
            if (values[i] == '(')
            {
                basePri+=2;
                pris[i] = -1;
            }
    
            if (values[i] == ')')
            {
                basePri-=2;
                pris[i] = -1;
            }
    
            if ((values[i] == '+') || (values[i] == '-'))
            {
                pris[i] = 1 + basePri;
            }
    
            if ((values[i] == '*') || (values[i] == '/'))
            {
                pris[i] = 2 + basePri;
            }
        }
    }
    
    //移除公式串和权重串中的括号字符
    void removeParentheses(vector<char>& values, vector<int>& pris)
    {
        for(int i = values.size(); i >= 0; --i)
        {
            if ((values[i] == '(') || (values[i] == ')'))
            {
                values.erase(values.begin()+i);
                pris.erase(pris.begin()+i);
            }
        }
    }
    /*获取可以计算的权重符的位置:
     如果左边操作符的权重>= 右边操作符的权重,那么左边操作符的左右数据可以进行计算
     如果左边操作符的权重< 右边操作符的权重,那么需要右边操作符和它的右边操作符进行比较。
    */
    int getCalPos(const vector<int>& pris)
    {
        //pris[0]是左数字, pris[1]是操作符  pris[2]是右数字
        for(int i = 1; i < pris.size(); i+=2)
        {
            if(i+2 < pris.size())
            {
                 if (pris[i] >= pris[i+2]) //如果左操作符的权重 >= 右操作符的权重,那么此左操作符可以计算
                 {
                     return i;
                 }
            }
        }
    
        return pris.size() - 2;
    }
    
    
    void calResult(vector<char>& values, vector<int>& pris)
    {
        while(values.size() != 1)
        {
            //获取可以计算的操作符的位置,并进行左右数字和操作符的计算
            int pos = getCalPos(pris);
            int result = realCal(values[pos-1], values[pos], values[pos+1]);
    
            //当左数字,操作符,右数字计算完后,删掉操作符和右数组的位置,左数字的位置改成计算结果。然后继续计算。
            //举例2*3+4 计算2*3得出6,删除*这个位置,3这个位置,2这个位置改成6.这样公式变成6+4.下次循环继续计算6+4
            values.erase(values.begin()+pos+1);
            pris.erase(pris.begin()+pos+1);
    
            values.erase(values.begin()+pos);
            pris.erase(pris.begin()+pos);
    
            values[pos-1] = result;;
            prtVecs(values);
        }
    }
    
    int main()
    {
        //原始字符串
        char data[]="2*3+(2*(5+6)*3)/2+4*6";
        vector<char> values;
        myCopy(values, data);
        cout << "origin:"; prtVecs(values);
       // prtVecs(values, pris);
        //计算原始字符串的权重
        vector<int> pris(values.size(),0);
        calPri(values, pris);
        //原始字符串去掉括号
        removeParentheses(values,pris);//把括号去掉
       // prtVecs(values, pris);
    
        calResult(values, pris);
    
        cout << "result:"; prtVecs(values);
    }
  • 相关阅读:
    发送电子邮件
    PHP Session
    Cookie
    Python基础语法
    Python中文编码
    Python简介
    PHP文件上传
    基于1.22.1版本的k8s部署
    k8s基于NFS创建动态存储StorageClass
    关于在k8s-v1.20以上版本使用nfs作为storageclass出现selfLink was empty, can‘t make reference
  • 原文地址:https://www.cnblogs.com/silentNight/p/14032968.html
Copyright © 2011-2022 走看看