当前位置: 首页 > article >正文

Leetcode224 -- 基本计算器及其拓展

题目分析:

其实这个计算器的实现并不难,因为除了括号就剩下加减法嘛,括号肯定比加减法先执行,但是加减法是同级的,只是会改变数字的正负号而已,所以实现的逻辑并不是很难,我们只需要一个栈,来保存当前的符号sign即可.
遇到 '(' 就将当前符号入栈
遇到 ')' 就将当前符号弹出
遇到 '+' 就获取栈顶的符号(注意不是弹出),因为+不改变方向,所以从栈中取出来什么就是什么

遇到 '-'  也获取栈顶的符号(注意不是弹出),但是 - 会改变方向,所以给取出来的符号取反即可
遇到数字 就一直向下计算,直到下一个符号不是数字
最后把每个阶段算出来的结果相加就是答案


代码实现:

class Solution {
	 public int calculate(String s) {
		 Deque<Integer> stack = new ArrayDeque<>();
		 stack.push(1);//这个栈中保存的是  符号
		 int sign = 1; // 整数  -1   +1 代表当前的符号
		 int res = 0,i = 0, n = s.length();
		 while(i < n) {
			 char c = s.charAt(i);
			 switch(c) {
				 case ' ':{
					 i++;
					 break;
				 }
				 case '+':{
					 i++;
					 sign = stack.peek();
					 break;
				 }
				 case '-':{
					 i++;
					 sign = -stack.peek();
					 break;
				 }
				 case '(':{
					 i++;
					 stack.push(sign);
					 break;
				 }
				 case ')':{
					 i++;
					 stack.pop();
					 break;
				 }
				 default:{
					 long sum = 0;
					 while(i < n && Character.isDigit(s.charAt(i))) {
						 sum = sum * 10 + s.charAt(i) - '0';
						 i++;
					 }
					 res += sum * sign;
				 }
			 }
		 }
		 return res;
	 }
}

题目拓展:

这个拓展是来自于Ks的一道面试题,也没有明确说明,但默认能猜出来是考什么

区别及实现思路:

先说一下和Leetcode224的区别,就是多了*/这两个符号,并且*/个加减不属于一个级别,*/优先于+-,所以这里扯到了优先级的概念,并且还有(),为了保证括号内的表达式先被计算,我们定义( 的优先级是最低的,这样定义了优先级之后,就很清晰了
实现思路如下:
1.遇到数字直接加到操作数列表
2.遇到优先级,与最近加入的优先级做对比,
        2.1 如果大于最近的优先级,则将操作符直接加入到操作符列表,
        2.2 否则从操作列表里拿一个操作符和两个操作数进行计算,将计算的结果加到原来的列表  

        重复上面的操作直到找到一个比当前操作符优先级更低的操作符(在列表中)或者列表为空,再将当前的操作符加入到列表。

        由于括号的优先级最高,我们要让括号里面的操作符最先被计算,所以可以将'('的优先级设为最低
 

代码实现:

 public double calculateKs(String expression) {
		 Deque<Double> numbers = new LinkedList<>();
		 Deque<Character> operators = new LinkedList<>();
		 
		 int index = 0,len = expression.length();
		 while(index < len) {
			 char c = expression.charAt(index);
			 
			 if(c == '(') {
				 operators.push(c);
				 index++;
			 }else if(c == ')') {
				 //计算括号内的表达式
				 while(operators.peek() != '(') {
					 //单点操作,不是连点操作,所以得循环一直算,直到不符合条件为止
					 compute(numbers,operators);
				 }
				 operators.pop();
				 index++;
			 }else if(isOperator(c)) {
				 //处理操作符,考虑优先级
				 while(!operators.isEmpty() && precedence(operators.peek())  >= precedence(c)) {
					//单点操作,不是连点操作,所以得循环一直算,直到不符合条件为止
					 compute(numbers,operators);
				 }
				 operators.push(c);
				 index++;
			 }else if(Character.isDigit(c)) {
				 //解析数字 -- 因为可能不只是一位数,所以要进行拼接
				 StringBuilder sb = new StringBuilder();
				 while(index < len && Character.isDigit(expression.charAt(index))) {
					 sb.append(expression.charAt(index++));
				 }
				 numbers.push(Double.parseDouble(sb.toString()));
			 }
		 }
		 
		 //计算剩余的操作
		 while(!operators.isEmpty()) {
			 //单点操作,不是连点操作,所以得循环一直算
			 compute(numbers,operators);
		 }
		 return numbers.pop();
	 }
	 
	 public boolean isOperator(char c) {
		 return c =='+' || c == '-' || c == '*' || c == '/';
	 }
	 
	 //定义操作符的优先级
	 public int precedence(char c) {
		 if(c == '+' || c == '-') {
			 return 1;
		 }else if(c == '*' || c == '/') {
			 return 2;
		 }
		 return 0;
	 }
	 
	 //单点操作,不是连点操作,所以就算一次
	 public void compute(Deque<Double> numbers,Deque<Character> operators) {
		 if(numbers.size() < 2) {
			 return;
		 }
		 double b = numbers.pop();
		 double a = numbers.pop();
		 char operator = operators.pop();
		 double res = 0.0;
		 
		 switch(operator) {
			 case '+':{
				 res = a + b;
				 break;
			 }
			 case '-':{
				 res = a - b;
				 break;
			 }
			 case '*':{
				 res = a * b;
				 break;
			 }
			 case '/':{
				 res = a / b;
				 break;
			 }
			 default:
				 break;
		 }
		 numbers. Push(res);
	 }


http://www.kler.cn/a/372964.html

相关文章:

  • Atlas800昇腾服务器(型号:3000)—SwinTransformer等NPU推理【图像分类】(九)
  • hvie SQL优化之where子句过滤模式
  • 瑞芯微RK3566/RK3568 Android11下该如何默认屏蔽导航栏/状态栏?看这篇文章就懂了
  • 数据库 示例解析
  • SQL语言基础
  • [0152].第3节:IDEA中工程与模块
  • Spring学习笔记_17——@Primary
  • 基于python的语音识别与蓝牙通信的温控系统毕设项目
  • 医学数据分析中的偏特征图可视化
  • 请详细介绍python三大神器:迭代器、生成器、装饰器
  • 数据结构练习题(链表)
  • 2024双11买什么东西比较好?双十一购物清单
  • 全面解读京东商品详情 API 接口:从功能到应用场景
  • 从0学习React(6)
  • k8s 1.28.2 集群部署 Thanos 对接 MinIO 实现 Prometheus 数据长期存储
  • GO语言微服务 服务注册与服务发现平台 - Nacos go sdk
  • 通过route访问Openshift上的HTTP request报错504 Gateway Time-out【已解决】
  • C#读取.ini配置文件
  • 手工方式屏蔽某一个网站
  • 利用摄像机实时接入分析平台LiteAIServer视频智能分析软件进行视频监控:过亮过暗检测算法详解
  • AHT20 HAL库驱动
  • 人工智能:开启未来之门
  • 如何分析算法的执行效率和资源消耗
  • 将本地某个commit 提交另一个分支上
  • Unity BesHttp插件修改Error log的格式
  • 数字信封原理解析:安全高效,一次一密!