最近在看《算法》这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下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. PHP通过XML报文格式的POST请求方式,与第三方接口交互(发送xml,获取XML,并解析xml步骤)

    开发者端:发送请求,并接收结果 <?php // 下面的demo,实现的功能如下: // 1-开发者需要判断一个用户是否存在,去请求第三方接口. // 2-与第三方接口的通信,是以xml格式传送 ...

  2. 处理Assetbundle依赖关系时想到的一道题

    在处理unit3d的assetbundle依赖关系的时候,想到了一道有趣的题目: 给定一堆数据,例如{A = {1, 3, 4}, B = {3, 4}, C = {5, 6}, D = {6, 7, ...

  3. 利用xhsell登录到远程腾讯云服务器

    xshell连接管理腾讯云服务器图文教程 打开xshell点击文件新建会话框 linux服务器ssh管理软件XSHELL下载及安装图文教程 输入公网IP地址确认下一步 选中服务器连接 一次性接受,不储 ...

  4. java从基础知识(八)泛型

    1.什么是泛型? 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法 ...

  5. C和指针 第十五章 错误报告perror和exit

    15.1 错误报告 perror 任何一种程序都存在出错的可能,包括系统的函数库,当出现错误时,系统提示发生错误,标准库函数在一个外部整型变量中保存错误代码,然后把错误代码传给用户程序,提示错误原因. ...

  6. Open xml 操作Excel 透视表(Pivot table)-- 实现Excel多语言报表

    我的一个ERP项目中,客户希望使用Excel Pivot table 做分析报表. ERP 从数据库中读出数据,导出到Excel中的数据源表(统一命名为Data),刷新Pivot table! 客户还 ...

  7. $.extend()和 $.fn.extend()

    1 $.extend()      jQuery.extend(): Merge the contents of two or moreobjects together into the first ...

  8. 使用Ruby来实现批量更新AD中字段

    准备工作 安装需要用到的gem gem install net-ldap gem install roo 准备好要更新的数据,比如exel表: /root/account.xlsx,内容如下 姓名 性 ...

  9. centos 6.7 搭建tornado + nginx + supervisor的方法(已经实践)

    首先,本来不想写这篇博客了,但是我测试了很多网上的例子包括简书的,全不行,我总结原因是自己太笨,搞了俩个晚上,后来决定,自己还是写一篇记录下来,保证自己以后使用 环境: centos6.7 64 py ...

  10. linux 比较两个文件是否一致

    diff source target 如果一致不弹出任何信息