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

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

示例 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. 聊聊依赖注入注解@Resource和@Autowired

    1. 前言 @Resource和@Autowired注解都可以在Spring Framework应用中进行声明式的依赖注入.而且面试中经常涉及到这两个注解的知识点.今天我们来总结一下它们. 2. @R ...

  2. Cookie默认不设置path时,哪些请求会携带cookie数据

    默认不设置path的时候,只会在请求和servlet同路径的情况下才会携带cookie中存储的数据,包含同级目录和下级目录 例如: 在http://localhost:8080/day01/test/ ...

  3. 微信小程序session_key解析中反斜杠问题处理 Java解析

    Java服务端微信小程序解密用户信息.手机号需用到session_key也需要decode,以下是官方描述: 加密数据解密算法 接口如果涉及敏感数据(如wx.getUserInfo当中的 openId ...

  4. SQL Msg 18054, Level 16, State 1

    今天接到一个看起来很简单的任务--修改数据库中的一项数据.听起来很简单吧. 在网上搜索了一下,很快就拼凑出了相应的 SQL 语句: UPDATE [suivi].[dbo].[numSerie]SET ...

  5. Brainman(规律题)【数学思想】

    Brainman 题目链接(点击) Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12942   Accepted: 650 ...

  6. Redis在CentOS for LInux上安装详细教程

    1.首先上传安装包,这里我以 redis-5.0.8.tar.gz 为例子. Linux下载redis地址:wget http://download.redis.io/releases/redis-5 ...

  7. MySQL 性能优化细节

    服务器层面优化(了解) 将数据保存在内存中,保证从内存读取数据 设置足够大的innodb_buffer_pool_size,将数据读取到内存中. 建议innodb_buffer_pool_size设置 ...

  8. python获取本地时间戳

    import time print(time.time())#获当前时间的时间戳 print(time.localtime())#获取本地时间 print(time.strftime('%Y-%m-% ...

  9. matlab实现梯度下降法(Gradient Descent)的一个例子

    在此记录使用matlab作梯度下降法(GD)求函数极值的一个例子: 问题设定: 1. 我们有一个$n$个数据点,每个数据点是一个$d$维的向量,向量组成一个data矩阵$\mathbf{X}\in \ ...

  10. jsc和luac文件 xxtea 解密.

    # -*- coding: utf-8 -*- import xxtea import os src = "./assets/src" dst = "./assets/s ...