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

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

示例 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()< )//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 = ;
static const int NUMBER_STATE = ;
static const int OPERATION_STATE = ;
stack<long int> number_stack;
stack<char> operation_stack;
long int number = ;
int STATE = STATE_BEGIN;
int compuate_flag = ; for(int i = ;i < s.length();i++)
{
if(s[i]==' ')
continue; switch(STATE)
{
case STATE_BEGIN:
if(s[i] >= '' && s[i] <= '')
{
STATE = NUMBER_STATE;
}
else
{
STATE = OPERATION_STATE;
}
i--;//back i
break; case NUMBER_STATE:
if(s[i] >= '' && s[i] <= '')
{
number = number * + s[i] - '';
}
else
{
number_stack.push(number);
if(compuate_flag == )
{
compute(number_stack,operation_stack);
}
number = ;
i--;
STATE = OPERATION_STATE;
}
break;
case OPERATION_STATE:
if(s[i] == '+' || s[i] == '-')
{
operation_stack.push(s[i]);
compuate_flag = ;
}
else if(s[i] == '(')
{
STATE = NUMBER_STATE;
compuate_flag = ; }
else if(s[i] >= '' && s[i] <= '')
{
STATE = NUMBER_STATE;
i--;
}
else if(s[i] == ')')
{ compute(number_stack,operation_stack);
}
break;
}
}
if(number != )
{
number_stack.push(number);
compute(number_stack,operation_stack);
}
if(number == && number_stack.empty())
{
return ;
}
return number_stack.top();
}
void compute (stack<long int> &number_stack ,stack<char> &operation_stack)
{
if(number_stack.size()< )//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进行测试就好啦

 #include<stdio.h>
#include<stack>
#include<iostream>
#include<string> using namespace std;
class Solution{
public:
long int calculate(string s)
{
static const int STATE_BEGIN = ;
static const int NUMBER_STATE = ;
static const int OPERATION_STATE = ;
stack<long int> number_stack;
stack<char> operation_stack;
long int number = ;
int STATE = STATE_BEGIN;
int compuate_flag = ; for(int i = ;i < s.length();i++)
{
if(s[i]==' ')
continue; switch(STATE)
{
case STATE_BEGIN:
if(s[i] >= '' && s[i] <= '')
{
STATE = NUMBER_STATE;
}
else
{
STATE = OPERATION_STATE;
}
i--;//back i
break; case NUMBER_STATE:
if(s[i] >= '' && s[i] <= '')
{
number = number * + s[i] - '';
}
else
{
number_stack.push(number);
if(compuate_flag == )
{
compute(number_stack,operation_stack);
}
number = ;
i--;
STATE = OPERATION_STATE;
}
break;
case OPERATION_STATE:
if(s[i] == '+' || s[i] == '-')
{
operation_stack.push(s[i]);
compuate_flag = ;
}
else if(s[i] == '(')
{
STATE = NUMBER_STATE;
compuate_flag = ; }
else if(s[i] >= '' && s[i] <= '')
{
STATE = NUMBER_STATE;
i--;
}
else if(s[i] == ')')
{ compute(number_stack,operation_stack);
}
break;
}
}
if(number != )
{
number_stack.push(number);
compute(number_stack,operation_stack);
}
if(number == && number_stack.empty())
{
return ;
}
return number_stack.top();
}
void compute (stack<long int> &number_stack ,stack<char> &operation_stack)
{
if(number_stack.size()< )//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();
}
};
int main()
{
string s = "1+121 - (14+(5-6) )";
Solution solve;
printf("%d\n",solve.calculate(s));
return ; }

整体代码

STL测试2)计算器简单实现的更多相关文章

  1. Android计算器简单逻辑实现

    Android计算器简单逻辑实现 引言: 我的android计算器的实现方式是:按钮输入一次,就处理一次. 但是如果你学过数据结构(栈),就可以使用表达式解析(前缀,后缀)处理. 而这个方式已经很成熟 ...

  2. python库的tkinter带你进入GUI世界(计算器简单功能)

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 一个处女座的程序猿 PS:如有需要Python学习资料的小伙伴可以加 ...

  3. 关于Spring-JDBC测试类的简单封装

    关于Spring-JDBC测试类的简单封装 1.简单封装 /** * Created with IntelliJ IDEA. * * @Author: Suhai * @Date: 2022/04/0 ...

  4. 让 API 测试变的简单。

    做开发已经四年有余了,之前在接口测试的时候最开始用的自己写的测试类进行测试,后来接触到了 postman 和 swagger ,虽然用起来比自己写的强太多了,但是总觉得差点事儿. 一方面是 postm ...

  5. C++ STL迭代器原理和简单实现

    1. 迭代器简介 为了提高C++编程的效率,STL(Standard Template Library)中提供了许多容器,包括vector.list.map.set等.然而有些容器(vector)可以 ...

  6. 测试cpu的简单工具-dhrystone【转】

    转自:https://blog.csdn.net/feixiaoxing/article/details/9005587 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...

  7. [Python设计模式] 第1章 计算器——简单工厂模式

    github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...

  8. ab压力测试工具的简单使用

    ab是一种用于测试Apache超文本传输协议(HTTP)服务器的工具.apache自带ab工具,可以测试 apache.IIs.tomcat.nginx等服务器 但是ab没有Jmeter.Loadru ...

  9. 【IDEA】单元测试:项目中引入JUnit测试框架+Mock简单了解

    一.Junit 使用和说明: 参考:单元测试第三弹--使用JUnit进行单元测试-HollisChuang's Blog http://www.hollischuang.com/archives/17 ...

随机推荐

  1. javaScript的执行机制-同步任务-异步任务-微任务-宏任务

    一.概念理解 1.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变.所以一切javascr ...

  2. sprintf 会自动追加’\0’至字符串末尾

    #define LEN_SERIAL_NUMBER (12) void C_CosemObjMeterInfo::SetSerialNum(U08 u08MeterId, U64 u64SerialN ...

  3. Pants On Fire(链式前向星存图、dfs)

    Pants On Fire 传送门:链接  来源:upc9653 题目描述 Donald and Mike are the leaders of the free world and haven't ...

  4. ojdbc6中OraclePreparedStatement的ArrayIndexOutOfBoundsException异常BUG-6396242

    现场信息 Caused by: java.lang.ArrayIndexOutOfBoundsException: -32203 at oracle.jdbc.driver.OraclePrepare ...

  5. CentOS7.5搭建spark2.3.1集群

    一 下载安装包 1 官方下载 官方下载地址:http://spark.apache.org/downloads.html 2  安装前提 Java8         安装成功 zookeeper  安 ...

  6. (四)Maven项目工程目录约定

    使用maven创建的工程我们称它为maven工程,maven工程具有一定的目录规范,如下: src/main/java 存放项目的.java文件 src/main/resources 存放项目资源文件 ...

  7. INSERT INTO语句的基本用法

    原文链接:https://www.cnblogs.com/mingmingming/p/11295200.html 一.INSERT INTO语句的基本用法 INSERT INTO 语句用于往表中插入 ...

  8. 读Linux高性能服务器编程-12章http服务器源码

    title:用线程池实现的http服务器 从main函数看起 解析ip地址(点分制, 端口号) 设置忽略SIGPIPE信号 初始化线程池,池中创建了8个线程,每个线程对应一个work函数 初始化htt ...

  9. 百度文本编辑器的toolbars属性值描述

    toolbars: [    [        'anchor', //锚点        'undo', //撤销        'redo', //重做        'bold', //加粗   ...

  10. cb34a_c++_STL_算法_查找算法_(7)_lower_bound

    cb34a_c++_STL_算法_查找算法_(7)_lower_bound//针对已序区间的查找算法,如set,multiset关联容器-自动排序lower_bound()--第一个可能的位置uppe ...