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()< )//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)计算器简单实现的更多相关文章
- Android计算器简单逻辑实现
Android计算器简单逻辑实现 引言: 我的android计算器的实现方式是:按钮输入一次,就处理一次. 但是如果你学过数据结构(栈),就可以使用表达式解析(前缀,后缀)处理. 而这个方式已经很成熟 ...
- python库的tkinter带你进入GUI世界(计算器简单功能)
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 一个处女座的程序猿 PS:如有需要Python学习资料的小伙伴可以加 ...
- 关于Spring-JDBC测试类的简单封装
关于Spring-JDBC测试类的简单封装 1.简单封装 /** * Created with IntelliJ IDEA. * * @Author: Suhai * @Date: 2022/04/0 ...
- 让 API 测试变的简单。
做开发已经四年有余了,之前在接口测试的时候最开始用的自己写的测试类进行测试,后来接触到了 postman 和 swagger ,虽然用起来比自己写的强太多了,但是总觉得差点事儿. 一方面是 postm ...
- C++ STL迭代器原理和简单实现
1. 迭代器简介 为了提高C++编程的效率,STL(Standard Template Library)中提供了许多容器,包括vector.list.map.set等.然而有些容器(vector)可以 ...
- 测试cpu的简单工具-dhrystone【转】
转自:https://blog.csdn.net/feixiaoxing/article/details/9005587 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...
- [Python设计模式] 第1章 计算器——简单工厂模式
github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...
- ab压力测试工具的简单使用
ab是一种用于测试Apache超文本传输协议(HTTP)服务器的工具.apache自带ab工具,可以测试 apache.IIs.tomcat.nginx等服务器 但是ab没有Jmeter.Loadru ...
- 【IDEA】单元测试:项目中引入JUnit测试框架+Mock简单了解
一.Junit 使用和说明: 参考:单元测试第三弹--使用JUnit进行单元测试-HollisChuang's Blog http://www.hollischuang.com/archives/17 ...
随机推荐
- Hive中row_number()、dense_rank()、rank()的区别
摘要 本文对Hive中常用的三个排序函数row_number().dense_rank().rank()的特性进行类比和总结,并通过笔者亲自动手写的一个小实验,直观展现这三个函数的特点. 三个排序函数 ...
- 8、react 高阶组件
1.高阶组件:封装 高阶组件使用得是react得一种模式,增强现有组件得功能 一个高阶组件就是一个函数,这个函数接收得是组件类作为参数得,并且返回得是一个新组件,再返回得新组件中有输入参数组件不具备得 ...
- Python中class的三种继承方法
class parent(object): def implicit(self): print("Parent implicit()") def override(self): p ...
- qt程序添加文件版本号
1.需要一个 *.rc 文件,用以保存相关信息.比如添加一个 app.rc 里面内容如下所示: IDI_ICON1 ICON DISCARDABLE "app.ico" ----- ...
- 调用webservice接口,报错:(十六进制值0x01)是无效的字符
#事故现场 调用webservice接口,报错:(十六进制值0x01)是无效的字符. 如图: 意思是webservice返回的信息中包含无效的字符,无法解析成xml: #分析 使用postman向we ...
- mysql explain的type的
导语 很多情况下,有很多人用各种select语句查询到了他们想要的数据后,往往便以为工作圆满结束了.这些事情往往发生在一些学生亦或刚入职场但之前又没有很好数据库基础的小白身上,但所谓闻道有先后,只要我 ...
- 《Redis开发与运维》
第1章 初识Redis 1. Redis介绍: Redis是一种基于键值对(key-value)的NoSQL数据库. 与很多键值对数据库不同的是,Redis中的值可以是由string(字符串).has ...
- java中HashMap原理?
参考:https://www.cnblogs.com/yuanblog/p/4441017.html(推荐) https://blog.csdn.net/a745233700/article/deta ...
- cb41a_c++_STL_算法_填充新值fill_generate
cb41a_c++_STL_算法_填充新值fill_generatefill(b,e,v)fill_n(b,n,v),填充n个vgenerate(b,e,p)generate_n(b,n,p) gen ...
- 关于GridView的横向合并数据信息
此为asp.net 运行展示: 前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeBehin ...