最近在看《算法》这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题。

import java.util.*;
/*
*
* 用来计算表达式
* for example: 1+2*3*(4+3*1)-3*1+2+3/1;
* (1+2*2-2*1*3*(1-1))*(1-2+3*(4+0));
* 注意点:
* 2.输入的表达书不能还有空格,括号必须匹配
* 基本思想:
* 1.建立操作数栈以及操作符栈
* 2.先去括号,每次遇到')'时,就退栈,直到遇到'('
* 3.然后处理括号中的表达式,先处理优先级高的,即*、/
* 4.处理好高优先级操作符之后,就处理+、-这种操作符
* 5.对以上的运算结果入栈,继续,处理完所有的(、)之后
* 6.然后再次求一般的表达式即可
*/ public class CalExpression { private Stack<Double > vals = new Stack<Double >();
private Stack<Character > ops = new Stack<Character >(); public static void main(String[] args) {
CalExpression obj = new CalExpression();
obj.input();
} public void input() {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
pushStack(in.next());
}
} public boolean check(char ch) {
if (ch == '(' || ch == ')' || ch == '+' || ch == '-'
|| ch == '*' || ch == '/') {
return true;
}
return false;
} public void pushStack(String str) {
//匹配非数字,将(、)、+、-、*、/作为分隔符
String[] strNum = str.split("[^0-9]"); Queue<Double > que = new LinkedList<Double >(); for (int i = 0; i < strNum.length; ++i) {
if (!strNum[i].equals("")) {
que.offer(Double.parseDouble(strNum[i]));
}
} boolean flag = false;
for (int i = 0; i < str.length(); ++i) {
if (check(str.charAt(i))) {
//匹配到右括号,需要计算括号中的内容
if (str.charAt(i) == ')') {
Deque<Character > ops_tmp = new LinkedList<Character >();
while (!ops.isEmpty() && ops.peek() != '(') {
ops_tmp.offerFirst(ops.pop());
}
//'('退栈
ops.pop();
calExpress(ops_tmp);
} else {
ops.push(str.charAt(i));
}
flag = false; } else if (!flag) {
vals.push(que.poll());
flag = true;
}
} double value = getValue(vals.iterator(), ops.iterator()); System.out.println(value);
vals.clear();
ops.clear(); } public void calExpress(Deque<Character > deq_ops) {
//操作数数目=操作符数目+1
int numCount = deq_ops.size() + 1; Deque<Double > deq_num = new LinkedList<Double >();
while (numCount > 0 && !vals.isEmpty()) {
deq_num.offerFirst(vals.pop());
numCount--;
} double value = getValue(deq_num.iterator(), deq_ops.iterator());
vals.push(value);
} public double getValue(Iterator it_num, Iterator it_ops) {
Deque<Double > vals = new LinkedList<Double >();
Deque<Character > ops = new LinkedList<Character >(); vals.offer((double)it_num.next());
while (it_num.hasNext()) {
char ch = (char)it_ops.next();
if (ch == '+' || ch == '-') {
vals.offer((double)it_num.next());
ops.offer(ch);
} else if (ch == '*' || ch == '/') {
double num = vals.pollLast();
if (ch == '*') {
vals.offer(num * (double)it_num.next());
} else {
vals.offer(num / (double)it_num.next());
}
}
} double value = vals.pollFirst();
while (!vals.isEmpty() && !ops.isEmpty()) {
if ((char)ops.pollFirst() == '+') {
value += vals.pollFirst();
} else {
value -= vals.pollFirst();
}
} return value;
} }

Java集合框架练习-计算表达式的值的更多相关文章

  1. Lambda表达式和Java集合框架

    本文github地址 前言 我们先从最熟悉的Java集合框架(Java Collections Framework, JCF)开始说起. 为引入Lambda表达式,Java8新增了java.util. ...

  2. 从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射

    从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射.Collection 接口又有 3 ...

  3. Asp.Net异常:"由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值"的解决方法

    今天项目中碰到一个以前从没有见过的异常信息“由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值”,于是查了一下资料,原来此异常是由于我在代码中使用了"Response.End ...

  4. 异常:Data = 由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值。

    做项目的时候,将DataTable序列化成Json,通过ashx向前台返回数据的时候,前台总是获取不到数据,但是程序运行却没问题, 没抛出异常.一时找不到办法,减小输出的数据量,这时前台可以接收到页面 ...

  5. C# 由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值。这个错误是什么原因引起的?

    C# 由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值.这个错误是什么原因引起的? 2011-12-17 22:45 提问者: 匿名|浏览次数:6056次 我来帮他解答 图片 符号 ...

  6. 【.NET】由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值。

    前言 上段时间做项目时,遇到如题之类问题,如今过去有一段时间了,具体出现的情形忘了,当时虽然找到了解决方法,但是依旧没有弄明白出现此种情况是何种原因,后来在微软的帮助支持中心找到了答案,特此记录,以防 ...

  7. 由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值。System.Threading.ThreadAbortException

    第一次遇到这样的错误 错误语法 try{ Response.Redirect("aa.aspx"); }catch (Exception ex){ Response.Redirec ...

  8. 【转】Java集合框架面试问题集锦

    Java集合框架(例如基本的数据结构)里包含了最常见的Java常见面试问题.很好地理解集合框架,可以帮助你理解和利用Java的一些高级特性.下面是面试Java核心技术的一些很实用的问题. Q:最常见的 ...

  9. Java中的函数式编程(五)Java集合框架中的高阶函数

    写在前面 随着Java 8引入了函数式接口和lambda表达式,Java 8中的集合框架(Java Collections Framework, JCF)也增加相应的接口以适应函数式编程.   本文的 ...

随机推荐

  1. 关于LESS

    LESS 是动态的样式表语言,通过简洁明了的语法定义,使编写 CSS 的工作变得非常简单. 翻译成大白话:写CSS算是体力活,并没有编程的感觉,不给前端人员装逼的机会,于是就搞了这玩意,相当于编程写C ...

  2. linux查看MySQL版本的四种方法

    1 在终端下执行 mysql -V 2 在help中查找 mysql --help |grep Distrib 3 在mysql 里查看 select version() 4 在mysql 里查看 s ...

  3. JavaScript葵花宝典之闭包

    闭包,写过JS脚本的人对这个词一定不陌生,都说闭包是JS中最奇幻的一个知识点,  虽然在工作中,项目里经常都会用到~  但是是不是你已经真正的对它足够的了解~~ 又或者是你代码中出现的闭包,并不是你刻 ...

  4. sql server 字符串转成日期格式

    在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...

  5. REDHAT一总复习1 输出重定向及head tail的用法

    1.使用bash命令,在server机上完成以下任务.(考点是:head  tail的使用) .显示/usr/bin/clean-binary-files文件的前12行,并将其输出到/home/stu ...

  6. controller_name classify constantize model_name

    控制器 class CourseSurveysController < ResourcesBaseController end controller_name # "course_su ...

  7. .NET中的异步

    .NET中4种异步方式? ThreadPool.QueueUserworkItem实现 APM模式(就是BeginXXX和EndXXX成对出现.) EAP模式(就是Event based, 准确说来就 ...

  8. 百度编辑器UEditor的使用方法

    百度编辑器具有丰富文本编辑功能,且开源免费,其使用方法如下: 1.在官网上下载对应的Uditor压缩包:http://ueditor.baidu.com/website/download.html 2 ...

  9. H5案例分享:JS手势框架 —— Hammer.js

    JS手势框架 -- Hammer.js 一.hammer.js简介 hammerJS是一个开源的,轻量级的触屏设备javascript手势库,它可以在不需要依赖其他东西的情况下识别触摸,鼠标事件.允许 ...

  10. clearfix的应用

    之前遇到一个问题,引用Bootstrap框架时 一行显示四个模块,小屏幕时显示两个模块 当内容一样时,大小屏幕时一样的,但是当其中一个和另一个内容不同时,展示效果就会有错乱 <div class ...