STL测试2)计算器简单实现

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格  。

示例 1:

输入: "1 + 1"
输出: 2
示例 2:

输入: " 2-1 + 2 "
输出: 3
示例 3:

输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23
说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/basic-calculator
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目大概如此,这里主要还是练习测试STL工具,难度不是特别大,但是在看书的时候发现他用了一种新的模式来进行计算 类似于不同状态之间的转换的一个方法对每种情况进行处理

那么先实现最基本的计算功能函数,因为这里只考了+ - 两种可能,没有乘除等因素影响,因此就只用考虑+ -运算而不用考虑乘除乘方等的优先级。

设计的数据结构是两个栈 一个是数据栈 一个是运算符栈,因为在出现括号的情况下要先把当前计算的结果和运算符保存起来,再进行运算,只有在出现括号结束的时候才可以进行最后运算进而保存,因此计算函数的需求就是从数据栈里取栈顶端两个元素和运算符栈顶的元素进行运算即可。

这里实现计算函数。

void compute (stack<long int> &number_stack ,stack<char> &operation_stack)
{
    if(number_stack.size()< 2)//special type like "(12345)"
    {

        return;
    }
    long int num2 = number_stack.top();
    number_stack.pop();
    long int num1 = number_stack.top();
    number_stack.pop();

    if(operation_stack.top() == '+')
    {

        number_stack.push(num1+num2);
    }
    else if(operation_stack.top()=='-')
    {

        number_stack.push(num1-num2);
    }
    operation_stack.pop();
}

接下来就是字符串的处理了。

我们考虑以下所有情况

可能的读入的内容为数字:数字有两种情况,一位数字或多位的数字,如果读入数字的下一个内容还是数字 只要当前数字*10+下一个数字即可得到正确的多位数。

可能的读入的内容为 + - 这时说明是直接运算的情况 只用把当前运算符先保存 再读入下一个数字即可运算结果并保存起来

可能的读入的内容为( 这时说明是有优先级的运算 也就是不能直接把下面的内容和之前的内容运算,需要把可以运算的flag设为0即先不运算,直到遇见)之后才把当前的结果和前面的结果进行运算

可能的读入的内容为)这时说明有优先级的运算已经结束,我们只需要直接进行运算即可

那么要注意的地方就是在一些情况下 比如读入的数字的时候读到的下一个内容不是数字 那么就需要对当前字符串处理的指针进行退格 不会阻碍后面的运算 因为整个循环里i是在一直自增的。

如此一来可以大致想想状态图是这样的

是一个三种状态之间的转换过程来对不同可能进行处理 具体的设计结束后就可以得到结果。

class Solution{
public:
    long int calculate(string s)
    {
        static const int STATE_BEGIN = 0;
        static const int NUMBER_STATE = 1;
        static const int OPERATION_STATE = 2;
        stack<long int> number_stack;
        stack<char> operation_stack;
        long int number = 0;
        int STATE = STATE_BEGIN;
        int compuate_flag = 0;

        for(int i = 0;i < s.length();i++)
        {
            if(s[i]==' ')
                continue;

        switch(STATE)
        {
        case STATE_BEGIN:
            if(s[i] >= '0' && s[i] <= '9')
            {
                STATE = NUMBER_STATE;
            }
            else
            {
                STATE = OPERATION_STATE;
            }
            i--;//back i
            break;

        case NUMBER_STATE:
            if(s[i] >= '0' && s[i] <= '9')
            {
                number = number * 10 + s[i] - '0';
            }
            else
            {
                number_stack.push(number);
                if(compuate_flag == 1)
                {
                    compute(number_stack,operation_stack);
                }
                number = 0;
                i--;
                STATE = OPERATION_STATE;
            }
            break;
        case OPERATION_STATE:
            if(s[i] == '+' || s[i] == '-')
            {
                operation_stack.push(s[i]);
                compuate_flag = 1;
            }
            else if(s[i] == '(')
            {
                STATE = NUMBER_STATE;
                compuate_flag = 0;

            }
            else if(s[i] >= '0' && s[i] <= '9')
            {
                STATE = NUMBER_STATE;
                i--;
            }
            else if(s[i] == ')')
            {

                compute(number_stack,operation_stack);
            }
            break;
            }
        }
        if(number != 0)
        {
            number_stack.push(number);
            compute(number_stack,operation_stack);
        }
        if(number == 0 && number_stack.empty())
        {
            return 0;
        }
        return number_stack.top();
    }
void compute (stack<long int> &number_stack ,stack<char> &operation_stack)
{
    if(number_stack.size()< 2)//special type like "(12345)"
    {

        return;
    }
    long int num2 = number_stack.top();
    number_stack.pop();
    long int num1 = number_stack.top();
    number_stack.pop();

    if(operation_stack.top() == '+')
    {

        number_stack.push(num1+num2);
    }
    else if(operation_stack.top()=='-')
    {

        number_stack.push(num1-num2);
    }
    operation_stack.pop();
}
};

最后我们随便设置一个string进行测试就好啦

  1 #include<stdio.h>
  2 #include<stack>
  3 #include<iostream>
  4 #include<string>
  5 
  6 using namespace std;
  7 class Solution{
  8 public:
  9     long int calculate(string s)
 10     {
 11         static const int STATE_BEGIN = 0;
 12         static const int NUMBER_STATE = 1;
 13         static const int OPERATION_STATE = 2;
 14         stack<long int> number_stack;
 15         stack<char> operation_stack;
 16         long int number = 0;
 17         int STATE = STATE_BEGIN;
 18         int compuate_flag = 0;
 19 
 20         for(int i = 0;i < s.length();i++)
 21         {
 22             if(s[i]==' ')
 23                 continue;
 24 
 25         switch(STATE)
 26         {
 27         case STATE_BEGIN:
 28             if(s[i] >= '0' && s[i] <= '9')
 29             {
 30                 STATE = NUMBER_STATE;
 31             }
 32             else
 33             {
 34                 STATE = OPERATION_STATE;
 35             }
 36             i--;//back i
 37             break;
 38 
 39         case NUMBER_STATE:
 40             if(s[i] >= '0' && s[i] <= '9')
 41             {
 42                 number = number * 10 + s[i] - '0';
 43             }
 44             else
 45             {
 46                 number_stack.push(number);
 47                 if(compuate_flag == 1)
 48                 {
 49                     compute(number_stack,operation_stack);
 50                 }
 51                 number = 0;
 52                 i--;
 53                 STATE = OPERATION_STATE;
 54             }
 55             break;
 56         case OPERATION_STATE:
 57             if(s[i] == '+' || s[i] == '-')
 58             {
 59                 operation_stack.push(s[i]);
 60                 compuate_flag = 1;
 61             }
 62             else if(s[i] == '(')
 63             {
 64                 STATE = NUMBER_STATE;
 65                 compuate_flag = 0;
 66 
 67             }
 68             else if(s[i] >= '0' && s[i] <= '9')
 69             {
 70                 STATE = NUMBER_STATE;
 71                 i--;
 72             }
 73             else if(s[i] == ')')
 74             {
 75 
 76                 compute(number_stack,operation_stack);
 77             }
 78             break;
 79             }
 80         }
 81         if(number != 0)
 82         {
 83             number_stack.push(number);
 84             compute(number_stack,operation_stack);
 85         }
 86         if(number == 0 && number_stack.empty())
 87         {
 88             return 0;
 89         }
 90         return number_stack.top();
 91     }
 92 void compute (stack<long int> &number_stack ,stack<char> &operation_stack)
 93 {
 94     if(number_stack.size()< 2)//special type like "(12345)"
 95     {
 96 
 97         return;
 98     }
 99     long int num2 = number_stack.top();
100     number_stack.pop();
101     long int num1 = number_stack.top();
102     number_stack.pop();
103 
104     if(operation_stack.top() == '+')
105     {
106 
107         number_stack.push(num1+num2);
108     }
109     else if(operation_stack.top()=='-')
110     {
111 
112         number_stack.push(num1-num2);
113     }
114     operation_stack.pop();
115 }
116 };
117 int main()
118 {
119     string s = "1+121 - (14+(5-6)  )";
120     Solution solve;
121     printf("%d
",solve.calculate(s));
122     return 0;
123 
124 }
整体代码
原文地址:https://www.cnblogs.com/KID-XiaoYuan/p/12207747.html