qfl_sdu_edu 2021-07-01 16:48 采纳率: 94.7%
浏览 34
已采纳

c语言计算器实现,请问该怎么写

要求能够处理括号,能够处理2*((1+2)+3+5/2)/2-6这种复杂公式。c语言实现,多谢!

  • 写回答

2条回答 默认 最新

  • qfl_sdu 2021-07-04 21:36
    关注

    代码如下,如有帮助,请采纳一下,谢谢。

    #include <iostream>
    #include <string>
    #include <list>
    using namespace std;
    //判断是否合法
    bool isValid(string &str)
    {
        char spec[] = {'+','-','*','/','{','}','[',']','(',')'};
        //删除空格
        unsigned int i=0,j=0;
        char buf[100] = {0};
        while(i<str.length())
        {
            if(str.at(i)== ' ')
            {
                i++;
                continue;
            }
            else
            {
                buf[j++] = str.at(i);
                i++;
            }
        }
        str = buf;
     
        unsigned int len = str.length();
        if (str.at(len -1) != '=')
        {
            cout << "公式需以=结束"<< endl;
            return false;
        }else
            str = str.substr(0,len-1);
        //判断是否有非数字的内容
        i = 0;
        len = str.length();
        while(i < len)
        {
            if(str.at(i)< '0' || str.at(i) > '9'   )
            {
                for (j =0;j<10;j++)
                {
                    if(str.at(i) == spec[j])
                        break;
                }
                if(j == 10)
                {
                    cout << "公式中存在非法字符:" << str.at(i)<< endl;
                    return false;
                }
                
            }
            i++;
        }
     
     
        //遇到3(2+3)、(2+3)3这种直接提示错误,不默认插入*
        i= 0;
        while(i < str.length()-1)
        {
            if(str.at(i) >= '0' && str.at(i) <= '9')
            {
                if(str.at(i+1)== '(' || str.at(i+1) == '[' || str.at(i+1) == '{')
                {
                    cout << "在" << str.at(i) << "和" << str.at(i+1) << "之间需要添加运算符" << endl;
                    return false;
                }
                
            }
            if(str.at(i)== ')' || str.at(i) == ']' || str.at(i) == '}')
            {
                if(str.at(i+1) >= '0' && str.at(i+1) <= '9')
                {
                    str.insert(i+1,1,'*');
                    cout << "在" << str.at(i) << "和" << str.at(i+1) << "之间需要添加运算符" << endl;
                    return false;
                }
            }
            i++;
        }
        return true;
    }
    //判断是否是数字
    bool isNmb(string s)
    {
        unsigned int i = 0;
        if(s.empty())
            return false;
        if(s.at(0) == '-')
        {
            i=1;
            while(i<s.length())
            {
                if(s.at(i) == '.')
                {
                    i++;
                    continue;
                }
                if(s.at(i)< '0' || s.at(i) >'9')
                    return false;
                i++;
            }
        }else
        {
            i = 0;
            while(i<s.length())
            {
                if(s.at(i) == '.')
                {
                    i++;
                    continue;
                }
                if(s.at(i)< '0' || s.at(i) >'9')
                    return false;
                i++;
            }
        }
        return true;
    }
     
    //判断数字是否是整数
    bool isZs(string s)
    {
        unsigned int i = 0;
        while(i<s.length())
        {
            if(s.at(i) == '.')
                return false;
            i++;
        }
        return true;
    }
     
    //处理一个最简单的计算公式--TO BE TEST
    bool DealSmple(string str,string &out)
    {
        unsigned int i =0,j=0;
        
        //将字符串分隔
        list<string> vp;
        int prepos =0;
        while(i<str.length())
        {
            if (str.at(i) == '+'  || str.at(i)=='*' || str.at(i) == '/' )
            {
                string tmp = str.substr(prepos,i-prepos);
                vp.push_back(tmp);
                vp.push_back(str.substr(i,1));
                i++;
                prepos = i;
            }else if( str.at(i) =='-') //查找连续--的情况
            {
                if( (i == 0) || (vp.size() > 0 && (vp.back().compare("+") == 0 || vp.back().compare("-") == 0 || vp.back().compare("*") == 0 || vp.back().compare("/") == 0)) ) //如果上一字符是-号,那么把当前的-留给下面的字符
                    i++;
                else
                {
                    string tmp = str.substr(prepos,i-prepos);
                    vp.push_back(tmp);
                    vp.push_back(str.substr(i,1));
                    i++;
                    prepos = i;
                }
            }
            else
                i++;
        }
        if(prepos == str.length())
        {
            cout << "公式中存在以"<< str.at(str.length()-1) << "结尾的非法公式段"<<endl;
            return false;
        }
        vp.push_back(str.substr(prepos,str.length() - prepos));
     
        //如果只有一个元素,直接退出
        if(vp.size() == 1)
        {
            out = vp.front();
            return true;
        }
     
        //计算乘法除法
        list<string>::iterator it = vp.begin();
        list<string>::iterator tmp;
        for (;it != vp.end();)
        {
            if(it->compare("*")==0 )//先处理乘法和除法
            {
                if (it == vp.begin())
                {
                    cout << "*出现在公式的开头"<< endl;
                    return false;
                }
                it++;
                if (it == vp.end())
                {
                    cout << "*出现在公式的末尾" << endl;
                    return false;
                }
                string nmb2 = *it;
                tmp = it;
                tmp--;
                vp.erase(it);
                it = tmp;
                tmp--;
                vp.erase(it);
                it = tmp;
                string nmb1 = *it;
     
                //判断是否是数字
                if ((!isNmb(nmb1)) || (!isNmb(nmb2)))
                {
                    cout << "存在多个连续的运算符或者数字个数不正确" << endl;
                    return false;
                }
     
     
                char val[20]={0};
                //判断两个数是否都是整数
                if (isZs(nmb1) && isZs(nmb2))
                {
                    int a = atoi(nmb1.c_str());
                    int b = atoi(nmb2.c_str());
                    int c = a*b;
                    itoa(c,val,10);
                }else
                {
                    double a = atof(nmb1.c_str());
                    double b = atof(nmb2.c_str());
                    double c = a*b;
                    gcvt(c,10,val);
                }
     
                it = vp.insert(it,val);
                it++;
                vp.erase(it);
     
     
                it = vp.begin();
            }else if (it->compare("/") == 0)
            {
                if (it == vp.begin())
                {
                    cout << "/出现在公式的开头"<< endl;
                    return false;
                }
                it++;
                if (it == vp.end())
                {
                    cout << "/出现在公式的末尾" << endl;
                    return false;
                }
                string nmb2 = *it;
                tmp = it;
                tmp--;
                vp.erase(it);
                it = tmp;
                tmp--;
                vp.erase(it);
                it = tmp;
                string nmb1 = *it;
     
                //判断是否是数字
                if ((!isNmb(nmb1)) || (!isNmb(nmb2)))
                {
                    cout << "存在多个连续的运算符或者数字个数不正确" << endl;
                    return false;
                }
     
                char val[20]={0};
                //判断两个数是否都是整数
                if (isZs(nmb1) && isZs(nmb2))
                {
                    int a = atoi(nmb1.c_str());
                    int b = atoi(nmb2.c_str());
                    if(b==0)
                    {
                        cout << "除数为0"<< endl;
                        return false;
                    }
                    int c = a/b;
                    itoa(c,val,10);
                }else
                {
                    double a = atof(nmb1.c_str());
                    double b = atof(nmb2.c_str());
                    if(b==0.0)
                    {
                        cout << "除数为0"<< endl;
                        return false;
                    }
                    double c = a/b;
                    gcvt(c,10,val);
                }
     
                it = vp.insert(it,val);
                it++;
                vp.erase(it);
     
                it = vp.begin();
            }else
                it++;
        }
     
        //计算加减
        bool iszhs = true;
        for (it=vp.begin();it != vp.end(); it++)
        {
            if (!isZs(*it))
            {
                iszhs = false;
                break;
            }
        }
        if (vp.size() == 1)
        {
            out = vp.front();
            return true;
        }else
        {
            if (iszhs)
            {
                int sum = 0;
                it = vp.begin();
                string tt = *it;
                sum += atoi(tt.c_str());
                it++;
                while(it != vp.end())
                {
                    string ts = *it;
                    it++;
                    if(it == vp.end())
                    {
                        cout << "公式运算中出现以运算符结尾的情况"<< endl;
                        return false;
                    }
                    string nmb3 = *it;
                    if (ts.compare("+") == 0)
                    {
                        sum += atoi(nmb3.c_str());
                    }else if (ts.compare("-") == 0)
                    {
                        sum -= atoi(nmb3.c_str());
                    }else
                    {
                        cout << "公式出现不匹配的运算符" << endl;
                        return false;
                    }
                    it++;
                }
     
                char bufout[20] ={0};
                itoa(sum,bufout,10);
                out = bufout;
                return true;
     
            }else
            {
                double sum = 0.0;
                it = vp.begin();
                string tt = *it;
                sum += atof(tt.c_str());
                it++;
                while(it != vp.end())
                {
                    string ts = *it;
                    it++;
                    if(it == vp.end())
                    {
                        cout << "公式运算中出现以运算符结尾的情况"<< endl;
                        return false;
                    }
                    string nmb3 = *it;
                    if (ts.compare("+") == 0)
                    {
                        sum += atof(nmb3.c_str());
                    }else if (ts.compare("-") == 0)
                    {
                        sum -= atof(nmb3.c_str());
                    }else
                    {
                        cout << "公式出现不匹配的运算符" << endl;
                        return false;
                    }
                    it++;
                }
     
                char bufout[20] ={0};
                gcvt(sum,10,bufout);
                out = bufout;
                return true;
            }
     
        }
     
     
     
        return true;
    }
     
    //处理括号
    bool DealKuhao(string &strSrc, char ch,char ch2)
    {
        //先处理小括号
        while(1)
        {
            int posEnd = strSrc.find(ch);
            if(posEnd < 0)
                return true;
            else if(posEnd == 0)
            {
                cout << ch <<"缺少对应的左括号" << endl;
                return false;
            }else
            {
                //找到与之对应的大括号
                int i = posEnd -1;
                while(i >=0 && strSrc.at(i) != ch2)
                    i--;
                if(i < 0)
                {
                    cout << ch << "没有与之配对的左括号" << endl;
                    return false;
                }
                string tmp = strSrc.substr(i+1,posEnd - i-1); //截取()之间的字符串
                string strout="";
                if(DealSmple(tmp,strout))  //处理()之间的公式,并返回处理结果
                {
                    strSrc = strSrc.substr(0,i) + strout + strSrc.substr(posEnd+1,strSrc.length() - posEnd);
                    //cout << "DealSmple " << ch << "  " << strSrc << endl;
                }else
                    return false;
            }
        }
        return true;
    }
     
     
     
     
    int main()
    {
        string strSrc,strout = "";
        cout << "请输入公式,以=号结束:" << endl;;
        getline(cin,strSrc);
     
        if(!isValid(strSrc))
            return 0;
     
        if(!DealKuhao(strSrc,')','('))
            return 0;
        if(!DealKuhao(strSrc,']','['))
            return 0;
        if(!DealKuhao(strSrc,'}','{'))
            return 0;
        DealSmple(strSrc,strout);
        cout << strout << endl;
     
        return 0;
     
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 我的R语言提示去除连锁不平衡时clump_data报错,图片以下所示,卡了好几天了,苦恼不知道如何解决,有人帮我看看怎么解决吗?
  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序