C++简单计算器的实现

语言 C++

工具

  • stack
  • map

步骤

  1. 初始化
  2. 读取字符串
  3. 去空格
  4. 负号处理
  5. 判断为空
  6. 检查格式
  7. 计算

示例在这里插入图片描述

代码

#include <iostream>
#include <string>
#include <stdio.h>
#include <stack>
#include <map>
#include <math.h>
#include <stdlib.h>
#include <sstream>
using namespace std;

char op[8][8];
map<char, int> m;
void init()
{
    m['+'] = 1, m['-'] = 2, m['*'] = 3, m['/'] = 4, m['('] = 5, m[')'] = 6, m['#'] = 7;
    op[1][1] = '>', op[1][2] = '>', op[1][3] = '<', op[1][4] = '<', op[1][5] = '<', op[1][6] = '>', op[1][7] = '>';
    op[2][1] = '>', op[2][2] = '>', op[2][3] = '<', op[2][4] = '<', op[2][5] = '<', op[2][6] = '>', op[2][7] = '>';
    op[3][1] = '>', op[3][2] = '>', op[3][3] = '>', op[3][4] = '>', op[3][5] = '<', op[3][6] = '>', op[2][7] = '>';
    op[4][1] = '>', op[4][2] = '>', op[4][3] = '>', op[4][4] = '>', op[4][5] = '<', op[4][6] = '>', op[2][7] = '>';
    op[5][1] = '<', op[5][2] = '<', op[5][3] = '<', op[5][4] = '<', op[5][5] = '<', op[5][6] = '=';
    op[6][1] = '>', op[6][2] = '>', op[6][3] = '>', op[6][4] = '>', op[6][6] = '>', op[6][7] = '>';
    op[7][1] = '<', op[7][2] = '<', op[7][3] = '<', op[7][4] = '<', op[7][5] = '<', op[7][7] = '=';
}
double operate(double num1, char oper, double num2)
{
   if(oper == '+')
        return num1 + num2;
   if(oper == '-')
        return num1 - num2;
   if(oper == '*')
        return num1 * num2;
   if(oper == '/')
        return num1 / num2;
}
string trim(string str)
{

    int index = 0;
    if( !str.empty())
    {
         while( (index = str.find(' ',index)) != string::npos)
        {
             str.erase(index,1);
         }
    }
    return str;
}
string change(string str)
{
    int  start;
    str+="#";
    for(int i = 0; i < str.length(); i++){
        if(str[i] == '-'){
            if(i == 0 || i != 0 && (m[str[i-1]] >= 1 && m[str[i-1]] <= 5)
                && str[i+1] >= '0' && str[i+1] <= '9'){
                    str += "   ";
                    int j = i+1;
                    start = j;
                    while(m[str[j]] == 0)
                        j++;

                    string s = str.substr(start, j-start);

                    for(int k = str.length() - 1; k >= j; k--)
                        str[k] = str[k-3];

                    str[i] = '(', str [i+1] = '0', str[i+2] = '-';

                    int l = i+3;
                    for(int k = 0; k < s.length(); k++){
                        str[l+k] = s[k];
                    }

                    str[l+s.length()] = ')';


               }
        }
    }
    str.erase(str.length()-1, 1);

    return str;
}
bool test(string str)
{
    bool flag = true;
    int ifNum = 0;
    stack<char> s;
    int start, e;
    str += "#";
    for(int i = 0; i < str.length(); i++){
        //判断非法字符

       if((str[i] < '0' || str[i] > '9') && m[str[i]] == 0 && str[i] != '.') return false;
       if(str[i] == '#' && i != str.length() - 1) return false;

        //判断小数点
       if(m[str[i]] == 0){
            if(ifNum == 0){
                start = i;
                ifNum = 1;
            }
        }
        if(m[str[i]] != 0){
            if(ifNum == 1){
                e = i;
                string s1 = str.substr(start, e - start);
                int pointNum = 0;
                if(s1[0] == '.') return false;
                for(int j = 0; j < s1.length(); j++){
                    if(s1[j] == '.')
                        pointNum++;
                }
                if(pointNum > 1)
                        return false;
            }
            ifNum = 0;
        }

        //判断符号
        if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/'){
                if(i == 0) return false;

                if((str[i-1] < '0' || str[i-1] > '9') && str[i-1] != ')') return false;

                if((str[i+1] < '0' || str[i+1] > '9') && str[i+1] != '(') return false;

        }

        //判断括号
        if(str[i] == '(') s.push(str[i]);
        if(str[i] == ')'){
            if(s.empty()) return false;
            char c = s.top();
            if(c == '(')
               s.pop();
            else
                return false;
        }
    }

    //判断括号
    if(s.empty() == false)
         flag = false;
    return flag;
}
void caculate(string str)
{
        str+="#";
        int flag = 0;
        int start, e;
        stack<double> numStack;
        stack<char> operStack;
        operStack.push('#');

        int index = 0;
        while(str[index] != '#' || operStack.top() != '#'){

                if(m[str[index]] == 0){
                    if(flag == 0){
                        start = index;
                        flag = 1;
                    }
                    index++;
                }

                else if(m[str[index]] != 0){
                    if(flag == 1){
                        e = index;
                        stringstream s (str.substr(start, e-start));
                        double num;
                        s >> num;
                        numStack.push(num);
                        flag = 0;

                    }
                    char c = operStack.top();
                    if(op[m[c]][m[str[index]]] == '<'){
                        operStack.push(str[index]);
                        index++;
                    }else if(op[m[c]][m[str[index]]] == '='){
                        operStack.pop();
                        index++;
                    }else{
                        char oper = operStack.top();
                        operStack.pop();
                        double num1 = numStack.top();
                        numStack.pop();
                        double num2 = numStack.top();
                        numStack.pop();
                        //printf("%f***%c***%f",num2,oper,num2);
                        double result = operate(num2, oper ,num1);
                        numStack.push(result);
                    }
                 }

            }
        printf("\t\t\t= %f\n",numStack.top());

}
int main()
{
    init();
    printf("\n\n\n\t\t\t请输入表达式,退出请输入end:\n");
    string s;
    while(1){
        printf("\n\t\t\t");
        string s;
        //cin >> noskipws >> s;
        getline(cin, s, '\n');
        s = trim(s); //去除空格
        s = change(s); //处理负数
        //cout << s;
        if(s == "end"){
            break;
        }
        else if(s.length() > 0){ //判断不为空
            if(!test(s))//检测格式
                printf("\t\t\t格式错误\n");
            else
                caculate(s); //计算
        }
        else{
            printf("\t\t\t输入不能为空\n");
        }
    }
    return 0;
}


有什么错误或者疑问请下方留言或加微信g1807069286

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值