- 浏览: 79040 次
- 性别:
- 来自: 拜月神教
最新评论
-
huangfenghit:
你绝对的大牛~
答复: 阿里巴巴面试感言 -
liuxuejin:
好!慢慢下载来看看
区间树 -
xiaobian:
看不懂,怎么知道是讲的好呢 ?
数据挖掘 决策树ID3算法原理 -
longay00:
不错,很牛,不过没有原理与实验很难相信它的正确性。从代码上看, ...
决策树C4.5算法 -
yangguo:
用我的study方法就可以了。
答复: java最优算法讨论
首先描述问题
首先进行的是括号优先级的处理
将每个字符逐一进栈,当扫描到")"时,进行出栈操作,直到栈顶元素等于"("
并记录出栈的"("与")"之间的字符串为subStr
然后是对subStr求后缀表达式,并计算结果
也就是这句代码
再把结果进栈
最后stack的内容是去掉括号的一个四则表达式
再进行一次CalculateReversePolishExpression方法,则得到最终结果
中缀转后缀表达式的基本思路
基本思路如下:
用一个链表 List<String> 储存将要生成的后缀表达式
用一个栈 Stack<String> 储存操作符
判断当前节点, 如果是操作数, 直接加入后缀表达式中, 如果是操作符,则比较前一个操作符和当前操作符的优先级,
如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符栈,如果遇到反括号 ')', 则在操作符栈中反向搜索,直到遇到匹配的正括号为止,将中间的操作符依次加到后缀表达式中。
然后是后缀表达式的计算
遍历储存后缀表达式的链表,将元素依次进栈,当遇到操作符时,连续出栈两个元素,进行运算,再将结果进栈,最后栈内留下的元素就是计算结果
最后再贴出茫茫多的代码
自己写的stack
stack节点
懒得copy的话下载附件
最近也想往编译原理那方面研究..
有什么好书推荐吗?
给定一个字符串 example:"4-(4-3*5+(2*4)+100)/10"; 要求输出结果"-5.70";结果四舍五入,保留两位小数
首先进行的是括号优先级的处理
public BigDecimal calculateString(String str) { char[] strs = str.toCharArray(); Stack<String> stack = new Stack<String>(); for (int i = 0; i < strs.length; i++) { String stackStr = String.valueOf(strs[i]); stack.push(stackStr); if (")".equals(stack.top())) { String subStr = null; while (!"(".equals(stack.top())) { stack.pop(); if (!"(".equals(stack.top())) { subStr = addEnd(subStr, stack.top()); } } String pushStr = CalculateReversePolishExpression(subStr); stack.pop(); stack.push(pushStr); } } String resultStr = null; while (stack.count != 0) { resultStr = CalculateReversePolishExpression(stack.toString()); } BigDecimal result = null; if (resultStr != null) { result = new BigDecimal(resultStr); } else { result = BigDecimal.ZERO; } return result.setScale(2, BigDecimal.ROUND_HALF_UP); }
将每个字符逐一进栈,当扫描到")"时,进行出栈操作,直到栈顶元素等于"("
并记录出栈的"("与")"之间的字符串为subStr
然后是对subStr求后缀表达式,并计算结果
也就是这句代码
String pushStr = CalculateReversePolishExpression(subStr);
再把结果进栈
最后stack的内容是去掉括号的一个四则表达式
再进行一次CalculateReversePolishExpression方法,则得到最终结果
中缀转后缀表达式的基本思路
基本思路如下:
用一个链表 List<String> 储存将要生成的后缀表达式
用一个栈 Stack<String> 储存操作符
判断当前节点, 如果是操作数, 直接加入后缀表达式中, 如果是操作符,则比较前一个操作符和当前操作符的优先级,
如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符栈,如果遇到反括号 ')', 则在操作符栈中反向搜索,直到遇到匹配的正括号为止,将中间的操作符依次加到后缀表达式中。
然后是后缀表达式的计算
遍历储存后缀表达式的链表,将元素依次进栈,当遇到操作符时,连续出栈两个元素,进行运算,再将结果进栈,最后栈内留下的元素就是计算结果
最后再贴出茫茫多的代码
package graph; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * 应用:逆波兰表达式 * * @author Leon.Chen * */ public class CalculateString { public BigDecimal calculateString(String str) { char[] strs = str.toCharArray(); Stack<String> stack = new Stack<String>(); for (int i = 0; i < strs.length; i++) { String stackStr = String.valueOf(strs[i]); stack.push(stackStr); if (")".equals(stack.top())) { String subStr = null; while (!"(".equals(stack.top())) { stack.pop(); if (!"(".equals(stack.top())) { subStr = addEnd(subStr, stack.top()); } } String pushStr = CalculateReversePolishExpression(subStr); stack.pop(); stack.push(pushStr); } } String resultStr = null; while (stack.count != 0) { resultStr = CalculateReversePolishExpression(stack.toString()); } BigDecimal result = null; if (resultStr != null) { result = new BigDecimal(resultStr); } else { result = BigDecimal.ZERO; } return result.setScale(2, BigDecimal.ROUND_HALF_UP); } public String[] matcher(String regex, String str) { Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(str); List<String> list = new ArrayList<String>(); while (matcher.find()) { list.add(matcher.group()); } String[] result = new String[list.size()]; return list.toArray(result); } public List<String> createReversePolishExpression(String subStr) { String regex = "\\d+\\.{0,1}\\d*"; String[] numbers = matcher(regex, subStr); String changeStr = subStr.replaceAll(regex, "0").replaceAll("\\-\\-0", "-1").replaceAll("\\+\\-0", "+1").replaceAll("\\*\\-0", "*1") .replaceAll("\\/\\-0", "/1"); char[] chars = changeStr.toCharArray(); int index = 0; List<String> list = new ArrayList<String>(); for (int i = 0; i < chars.length; i++) { String str = String.valueOf(chars[i]); if ("0".equals(str)) { list.add(numbers[index++]); } else if ("1".equals(str)) { list.add("-" + numbers[index++]); } else { list.add(str); } } List<String> suffix = new ArrayList<String>(); Stack<String> operator = new Stack<String>(); for (int i = 0; i < list.size(); i++) { if (!isOperatorType(list.get(i))) { suffix.add(list.get(i)); } else { if (operator.count == 0) { operator.push(list.get(i)); } else { while (operator.count != 0&&compare(operator.top(), list.get(i)) >= 0) { String top = operator.top(); operator.pop(); suffix.add(top); } operator.push(list.get(i)); } } } while (operator.count != 0) { suffix.add(operator.top()); operator.pop(); } return suffix; } public String CalculateReversePolishExpression(String subStr) { List<String> suffix = createReversePolishExpression(subStr); Stack<Double> stack = new Stack<Double>(); for (int i = 0; i < suffix.size(); i++) { if (!isOperatorType(suffix.get(i))) { stack.push(Double.valueOf(suffix.get(i))); } else { Double current = stack.top(); stack.pop(); Double previous = null; if (stack.count != 0) { previous = stack.top(); stack.pop(); } else { previous = new Double(0); } Double result = calculate(suffix.get(i), previous, current); stack.push(result); } } return stack.top().toString(); } public String addEnd(String str, String a) { StringBuffer buf = new StringBuffer(); buf.append(a); if (str != null) { buf.append(str); } return buf.toString(); } public boolean isOperatorType(String str) { if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")) { return true; } return false; } public int compare(String op1, String op2) { Integer iop1 = getOperator(op1); Integer iop2 = getOperator(op2); return iop1.compareTo(iop2); } public Integer getOperator(String op) { if ("+".equals(op) || "-".equals(op)) { return new Integer(0); } if ("*".equals(op) || "/".equals(op)) { return new Integer(1); } return null; } public Double calculate(String op, Double previous, Double current) { if ("+".equals(op)) { return previous + current; } if ("-".equals(op)) { return previous - current; } if ("*".equals(op)) { return previous * current; } if ("/".equals(op)) { return previous / current; } return null; } public static void main(String[] args) { String[] strs = new String[]{"(5+6)*7","(-1)/(-3)","1/(-3)","-1/7","7+(3*5)-(8+20/2)","4-(4-3*5+(2*4)+100)/10"}; for(int i=0;i<strs.length;i++){ BigDecimal result = new CalculateString().calculateString(strs[i]); System.out.println(result.toString()); } } }
自己写的stack
package graph; public class Stack<T> { public StackNode<T> stackTop; public int count; public void push(T info) { StackNode<T> node = new StackNode<T>(); node.info = info; node.link = stackTop; stackTop = node; count++; } public void pop() { if(stackTop == null) { System.out.println("null stack"); } else { stackTop = stackTop.link; count--; } } public boolean isEmpty() { return count == 0; } public T top() { if(stackTop == null) { return null; } return stackTop.info; } public String toString(){ Stack<T> other = new Stack<T>(); while(count != 0){ T top = top(); pop(); other.push(top); } StringBuffer buf = new StringBuffer(); while(other.count !=0){ buf.append(other.top()); other.pop(); } return buf.toString(); } }
stack节点
package graph; public class StackNode<T> { public StackNode<T> link; public T info; }
懒得copy的话下载附件
- CalculateString.rar (2.1 KB)
- 描述: 源代码
- 下载次数: 259
评论
5 楼
only_xxp
2010-08-19
学习!!!
4 楼
mingjian01
2010-08-18
如果我只想将一个中缀表达式完整转为后缀表达式,不想中间有计算结果,程序应该怎样写
3 楼
dogstar
2008-04-25
龙书一本.
2 楼
leon_a
2008-04-24
引用
我想说,如果你看了 编译原理,会有更大的收获。
努力!
努力!
最近也想往编译原理那方面研究..
有什么好书推荐吗?
1 楼
yananay
2008-04-24
我想说,如果你看了 编译原理,会有更大的收获。
努力!
努力!
发表评论
-
庞果英雄会 覆盖数字
2013-11-14 15:13 856庞果覆盖数字原题如下 给定整数区间[a,b]和整数区间[x, ... -
2-3 tree
2013-10-09 17:10 772package com.leon.cc; imp ... -
编译原理生成LL1预测分析表
2013-08-11 20:47 5850package com.leon; impo ... -
应用倍增法后缀数组以及RMQ求解N个字符串最长公共子串问题
2011-11-30 16:35 1464/** * @see IOI2009国家集训队论文《后 ... -
谷哥的KOF连招问题
2010-10-09 14:38 1533传说问题是这样的 玩过KOF(拳皇)的人都知道,玩的时候会连招 ... -
KOF
2010-10-09 00:13 0package org.struct.trietree; ... -
ACM/ICPC HDU 1195
2010-09-06 10:37 1897本年度还有8篇博客需要完成 开篇前附加一个看完《盗梦空间》的我 ... -
答复: 阿里巴巴面试感言
2009-10-09 22:27 2185好吧,我承认我闲的蛋疼 问题:3000万条的记录取最大的前50 ... -
正向最大匹配改进算法
2009-05-26 22:11 5894AD.: 2年J2EE经验,熟悉常用数据结构算法,熟悉常 ... -
决策树C4.5算法
2009-05-19 02:05 5259数据挖掘中决策树C4.5预测算法实现(半成品,还要写规则后 ... -
区间树
2008-07-18 15:47 2192package acmcode; /** * ... -
红黑树初版
2008-07-16 17:20 1610package acmcode; /** * R ... -
最大0,1子矩阵
2008-04-20 21:16 6087首先描述一下问题 /** * * 时间限制(普 ... -
数据挖掘 决策树ID3算法原理
2008-04-11 22:24 11414上一篇博客写了ID3算法的简单实现 这一篇讲讲ID3的原理 写 ... -
决策树ID3算法
2008-04-01 22:18 7607算了,还是自己修正一个BUG.... package gr ... -
ext2.0 的XMLWriter
2008-02-20 21:04 1285做ext相关的一个example项目,把我们的客户端移植成ex ... -
树与哈夫曼树
2008-02-20 20:50 1593package tree; public ... -
LCS与图算法
2008-02-20 20:46 1236求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个 ... -
《程序员》算法擂台:骑士聚会
2008-02-20 20:40 1217在8×8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士 ...
相关推荐
逆波兰表达式求值是计算机科学中的一个重要概念,主要用于避免使用括号来表示运算优先级,从而简化表达式的解析过程。逆波兰表达式,又称后缀表达式,是一种没有括号、无需考虑运算符优先级的数学表达式书写方式。在...
标题 "四则运算求值(中缀转逆波兰式)" 涉及到的是计算机科学中的算法问题,主要集中在表达式求值和转换方法上。逆波兰表示法(Reverse Polish Notation,RPN),也被称为后缀表示法,是一种没有括号的数学表达式...
本篇将详细介绍从中缀表达式转换为后缀表达式的方法,并探讨如何使用C语言实现四则运算。 中缀表达式是我们日常生活中最常见的表达式形式,例如 \(2 + 3 * 4\)。在这个表达式中,运算符位于操作数之间。然而,这种...
2. **后缀表达式**,又称逆波兰表示法,如 "2 3 4 * +”。在这个表示法中,运算符紧跟在其操作数之后。后缀表达式的求值非常简单,只需一个栈即可,因为每个操作数遇到后立即压栈,遇到运算符时,弹出栈顶的两个操作...
后缀表达式(也称为逆波兰表示法或RPN)是一种将操作数放在操作符前面的表达式表示方法。相较于中缀表达式,后缀表达式的优势在于: - **无需考虑操作符的优先级**:在后缀表达式中,操作符总是跟在其操作数之后,...
然而,在计算机内部处理时,后缀表达式(也称为逆波兰表示法)更为方便,因为它不需要括号来明确运算顺序,如 \(2 3 4 * +\)。本文将详细介绍如何通过C语言实现一个将中缀表达式转换为后缀表达式的算法。 首先,...
此外,当前的代码仅支持基本的四则运算,不包括指数、开方等更复杂的数学运算,也不包含错误处理机制,比如除数为零的情况。 总之,该C语言程序提供了一个完整的框架,用于理解和实现后缀表达式的求值过程,特别...
逆波兰表达式(Reverse Polish Notation,RPN)算法是一种基于后缀表示法的计算方法,主要用于解决数学表达式的求值问题。它将运算符放置在操作数之后,避免了括号的使用,使得表达式求值的过程更为直观。在这个算法...
### 利用堆栈实现逆波兰表达式(后缀法) #### 一、逆波兰表达式简介 逆波兰表达式,又称后缀表达式或后缀记法,是一种没有括号且运算符位于操作数之后的数学表达式书写方式。在计算机科学中,这种表达式被广泛...
人们熟悉的四则运算表达式称为中缀表达式,例如(23+34*45/(5+6+7))。在程序设计语言中,可以利用堆栈的方法把中缀表达式转换成保值的后缀表达式(又称逆波兰表示法),并最终变为计算机可以直接执行的指令,得到...
在处理这类表达式时,我们通常需要将其转换或直接解析为后缀表达式(也称为逆波兰表示法),因为后缀表达式更适合于简单的栈操作进行求值。然而,通过巧妙地利用栈结构,我们也可以直接对中缀表达式进行求值。本文将...
- **后缀表达式(逆波兰表示法)**:与中缀表达式不同,在后缀表达式中,操作符位于其操作数之后,例如上述的中缀表达式转换为后缀表达式为`3 4 2 * +`。 #### 知识点二:转换算法概述 为了实现题目中的要求,我们...
在计算24点游戏中,逆波兰表达式可以简化计算过程,避免了中缀表达式(常规的运算符在操作数之间的表达式)转换成后缀表达式(即逆波兰表达式)的步骤。本文将详细讲解如何用C语言实现一个基于逆波兰表达式的24点...
在IT领域,四则运算表达式的转换和计算是计算机科学中的基本问题,特别是在编译原理、数据结构和算法设计中。这里我们主要讨论如何将中缀表达式转换为后缀表达式(也称为逆波兰表示法)以及如何计算后缀表达式的结果...
然而,计算机处理这种表达式时不如处理后缀表达式(逆波兰式)来得直接。后缀表达式是将运算符放在操作数之后的形式,例如,上述中缀表达式对应的后缀表达式为 \(2 3 4 * +\)。这样的表示方式使得求值过程无需使用栈...
使用逆波兰表达式实现的四则运算解析库、计算器(JavaScript) 功能 任意顺序的四则+-*/运算 支持() 前端后端通用 提供直接计算函数 提供四则运算表达式转逆波兰AST函数 提供语法分析函数(暂时只支持上下两个字符...