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

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

示例 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. 曹工说JDK源码(3)--ConcurrentHashMap,Hash算法优化、位运算揭秘

    hashcode,有点讲究 什么是好的hashcode,一般来说,一个hashcode,一般用int来表示,32位. 下面两个hashcode,大家觉得怎么样? 0111 1111 1111 1111 ...

  2. Python--编码转换

    # -*- coding:gbk -*- # 即使设置文件编码为gbk,下方定义的字符串s1依旧为unicode # 获取默认编码格式 import sys print(sys.getdefaulte ...

  3. Linux 云服务器运维(操作及命令)

    1. 什么是linux服务器load average? Load是用来度量服务器工作量的大小,即计算机cpu任务执行队列的长度,值越大,表明包括正在运行和待运行的进程数越多. 2. 如何查看linux ...

  4. Chosen by god【组合数打表】

    Chosen by god 题目链接(点击) Everyone knows there is a computer game names "hearth stone", recen ...

  5. Docker学习 ,超全文档!

    我们的口号是:再小的帆也能远航,人生不设限!!        一.学习规划: Docker概述 Docker安装 Docker命令 Docker镜像 镜像命令 容器命令 操作命令 容器数据卷  Doc ...

  6. Mysql:bit类型的查询与插入

    原文链接:https://www.cnblogs.com/cuizhf/archive/2013/05/17/3083988.html Mysql关于bit类型的用法: 官方的资料如下: 9.1.5. ...

  7. opencv C++矩阵操作

    int main(){ cv::Mat src1=(cv::Mat_<float>(2,3)<<1,2,3,4,5,6); cv::Mat src2=(cv::Mat_< ...

  8. Swagger之外的选择

    今天给大家安利一款接口文档生成器--JApiDocs. swagger想必大家都用过吧,非常方便,功能也十分强大.如果要说swaager有什么缺点,想必就是注解写起来比较麻烦.如果我说有一款不用写注解 ...

  9. CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试

    微服务测试的痛点与挑战 这张图可以形象地展示单体服务和微服务的对比,单体应用就像左边巨大的集装箱,软件模块和应用都包括其中:而微服务就像是由一个小集装箱组成,微小的服务组成一个庞大.完整的系统.单体服 ...

  10. 黎活明8天快速掌握android视频教程--19_采用ListView实现数据列表显示

    1.首先整个程序也是采用mvc的框架 DbOpenHelper 类 package dB; import android.content.Context; import android.databas ...