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

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

示例 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. android日常开发总结的技术经验60条

    全部Activity可继承自BaseActivity,便于统一风格与处理公共事件,构建对话框统一构建器的建立,万一需要整体变动,一处修改到处有效. 数据库表段字段常量和SQL逻辑分离,更清晰,建议使用 ...

  2. 网络编程-Netty-Reactor模型

    目录 # 摘要 高性能服务器 Reactor模式 Reactor单线程模型设计 Reactor多线程模型设计 主从Reactor多线程模型设计 Netty Reactor模型设计 参考 你的鼓励也是我 ...

  3. 使用 Kafka + Spark Streaming + Cassandra 构建数据实时处理引擎

    Apache Kafka 是一个可扩展,高性能,低延迟的平台,允许我们像消息系统一样读取和写入数据.我们可以很容易地在 Java 中使用 Kafka. Spark Streaming 是 Apache ...

  4. (八)利用 Profile 构建不同环境的部署包

    接上回继续,项目开发好以后,通常要在多个环境部署,象我们公司多达5种环境:本机环境(local).(开发小组内自测的)开发环境(dev).(提供给测试团队的)测试环境(test).预发布环境(pre) ...

  5. 初识Redis的数据类型HyperLogLog

    前提 未来一段时间开发的项目或者需求会大量使用到Redis,趁着这段时间业务并不太繁忙,抽点时间预习和复习Redis的相关内容.刚好看到博客下面的UV和PV统计,想到了最近看书里面提到的HyperLo ...

  6. typora中的图片处理20200622

    typora中的图片处理20200622 食用建议 typora作为markdown的书写神器,一般习惯的流程是在typora中写完,然后复制粘贴到博客园中,然而,markdown中图片采用的是本地连 ...

  7. Elasticsearch修改分词器以及自定义分词器

    Elasticsearch修改分词器以及自定义分词器 参考博客:https://blog.csdn.net/shuimofengyang/article/details/88973597

  8. Redis SDS 深入一点,看到更多!

    1.什么是SDS? Redis 自定的字符串存储结构,关于redis,你需要了解的几点!中我们对此有过简要说明. Redis 底层是用C语言编写的,可是在字符存储上,并未使用C原生的String类型, ...

  9. el-switch 初始值(默认值)不能正确显示状态问题

    <el-table-column align="center" label="状态">       <template slot-scope= ...

  10. Shader专题:卡通着色(一)控制颜色的艺术

    什么是 Shader? 关于什么是 Shader ,各种百科各种教程都有说过,但是今天我们就从一个另一个角度去试着理解什么是 Shader? 我们先看下 Shade 的英文意思,如下: v.给...遮 ...