四则运算计算器的C++实现(借助STL)

说明

实现具有加减乘除和乘方(幂运算)的整形数字运算功能的计算器,且支持带括号的运算。以字符串形式作为输入。

思路:

根据运算符优先级的大小分层的思想来完成设计。由于括号的优先级最高,第一层需要解析出字符串中的括号;首先准备一个栈stack,从左向右判断每一个字符如果不是右括号")“则入栈,直到碰到右括号,开始出栈,遇到第一个出栈的左括号”(“为止,两个括号中间的字符组成的运算优先级最高,进行计算,将结果转为字符入栈,直至原始字符串中所有的字符入栈;第二层借助两个向量vector,一个是vector一个是vector分别存放字符串中的数字和运算符,从左向右按字符串顺序解析;第三层,由于运算符中乘方的优先级最高,因此遍历符号向量,遇到”^“时,计算对应数字向量中两个数字的乘方,依次“剔除”所有幂符号;第四层,剩下的运算符中,乘除的优先级高于加减,采取第三层同样的思路,从左向右遍历剩余运算法,遇到乘除则计算,完成"×"和”/“的运算;第五层,符号vector中只剩余"+"和”-",从左向右完成数字vector中的加减法运算。按照以上分层思路即可轻松实现。

流程图:

在这里插入图片描述

代码如下:

//实现一个计算器功能
#include <iostream>      
#include <vector>
#include <stack>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <math.h>

using namespace std;

/*================================================

calc() 分离字符串中的数字和运算符
statistics() 统计字符串中的数字和运算符
calculation() 计算字符串的值
del_power() 去除字符串中的乘方
del_multi() 去除字符串中的乘号和除号

=================================================*/

/* 函数声明 */
void del_multi(vector<int> num, vector<char> symbol, int* add_sub_num, char* add_sub_symbol, int* symbol_length);
void del_power(vector<int> &num, vector<char> &symbol);
void statistics(const char* expr, int expr_len, vector<int> &num, vector<char> &symbol);
int calculation(const char* expr);
int calc(const char* expr);

/* 识别括号 */
int calc(const char* expr)
{
    int expr_len = strlen(expr);
    stack<char> element;

    for(int i = 0; i < expr_len; i++)
    {
        if(expr[i] != ')')
        {
            element.push(expr[i]);
        }
        else
        {
            string strTemp = "";
            while(element.top() != '(')            /* 判断一对括号 */
            {
                strTemp = element.top() + strTemp;
                element.pop();
            }
            element.pop();
            int result = calculation(strTemp.c_str());  /* 将括号内的运算完成计算 */
            stack<char> temp;

            while (result != 0)
            {
                temp.push((result % 10) + '0');
                result = result / 10;
            }

            while(!temp.empty())
            {
                element.push(temp.top());
                temp.pop();
            }
        }  
    }
    string str = "";

    while(!element.empty())
    {
        str = element.top() + str;
        element.pop();
    }
    int result = calculation(str.c_str());      /* 计算不含有括号的字符串 */
    return result;
}

/* 计算解析完成的不带括号的字符串 */
int calculation(const char* expr)
{
    int expr_len = strlen(expr);
    int result = 0;
    vector<int> num;       //数字vector
    vector<char> symbol;   //运算符vector

    statistics(expr, expr_len, num, symbol);   //字符串解析出数字和运算符

    del_power(num, symbol);                  /* 去除乘方 */

    int symbol_len = symbol.size();

    int* add_sub_num = new int[symbol_len + 1];   //数字长度比运算符多1
    char* add_sub_symbol = new char[symbol_len];
    int symbol_length = 0;

    del_multi(num, symbol, add_sub_num, add_sub_symbol, &symbol_length);     /* 去除乘除号 */

    result = add_sub_num[0];
    for(int iter = 0; iter < symbol_length; ++iter)
    {
        if('+' == add_sub_symbol[iter])
        {
            result += add_sub_num[iter + 1];
        }   
        else
        {
            result -= add_sub_num[iter + 1];
        }           
    }

    //cout<<"the result is: "<<result<<endl;
    delete[] add_sub_num;
    delete[] add_sub_symbol;
    return result;
}

/* 解析出字符串中的数字和运算符 */
void statistics(const char* expr, int expr_len, vector<int> &num, vector<char> &symbol)
{
    int temp = 0;

    for(int expr_element = 0; expr_element < expr_len; expr_element++)
    {
        if('0' <= expr[expr_element] && expr[expr_element] <= '9')
        {
            temp = temp * 10 + (expr[expr_element] - '0');
        }
        if(('+' == expr[expr_element]) || ('-' == expr[expr_element]) || ('*' == expr[expr_element]) || ('/' == expr[expr_element]) || ('^' == expr[expr_element]))
        {
            num.push_back(temp);
            symbol.push_back(expr[expr_element]);
            temp = 0;
        }
    }
    num.push_back(temp);
}

/* 去除运算符中的乘号和除号 */
void del_multi(vector<int> num, vector<char> symbol, int* add_sub_num, char* add_sub_symbol, int* symbol_length)
{
    int symbol_len = symbol.size();
    int len = 0;
    int i;

    for(i = 0;i < symbol_len; i++)
    {
        if('*' == symbol[i])
        {
            num[i + 1] = num[i] * num[i + 1];
        }
        else if('/' == symbol[i])
        {
            num[i + 1] = num[i] / num[i + 1];
        }
        else
        {
            add_sub_num[len] = num[i];
            add_sub_symbol[len] = symbol[i];
            len++;
        }
    }
    add_sub_num[len] = num[i];
    *symbol_length = len;
}

/* 去除运算符中的乘方符号 */
void del_power(vector<int> &num, vector<char> &symbol)
{
    vector<int> del_power_num;
    vector<char> del_power_symbol;
    int symbol_len = symbol.size();
    int i;

    for(i = 0; i < symbol_len; i++)
    {
        if('^' == symbol[i])
        {
            num[i + 1] = pow(num[i], num[i + 1]);
        }
        else
        {
            del_power_num.push_back(num[i]);
            del_power_symbol.push_back(symbol[i]);
        }
    }

    del_power_num.push_back(num[i]);
    num.assign(del_power_num.begin(),del_power_num.end());
    symbol.assign(del_power_symbol.begin(),del_power_symbol.end());
}

int main()
{
    cout<<"测试用例:"<<endl;
    cout<<"1+2*3+4-5 = "<<calc("1+2*3+4-5")<<endl;
    cout<<"3^3*4+6/3 = "<<calc("3^3*4+6/3")<<endl;
    cout<<"(3+2)*((3+9)/3) = "<<calc("(3+2)*((3+9)/3)")<<endl;
    cout<<"5+6*2/(2+1)-9+2^10 = "<<calc("5+6*2/(2+1)-9+2^10")<<endl;
    cout<<"((3-1)*(5-2)+10)/2^3 = "<<calc("((3-1)*(5-2)+10)/2^3")<<endl;
    system("pause");
    return 0;
}

测试结果:

在这里插入图片描述

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值