Ⅰ java :转变为逆波兰表示式的代码报错:堆栈溢出,怎么解决
while(Character.isDigit(chars[i])||chars[i]=='.') {
s.append(chars[i]);
}
这一段是死循环。。stack一直追加参数,所以溢出了
Ⅱ Java计算字符串中的数学表达式的值算法怎么写
代码网上很多,只说说算法吧
12+8/4-5+(3-4)
把这样的表达式拆成:(操作数)(操作符) 、
12+
8/
4-
5+(
3-
4)
(术语叫做逆波兰式)
默认的计算顺序是从左往右,记为left。另设从右往左,记为right
设计Element类,具有 操作数 operant, 操作符operator, 操作顺序 order三个属性
用两个先进后出的栈结构Stack<Element> a,b;
一开始所有的Element都在a中,逐个弹出计算合并值,
当遇到乘、除、括号时计算顺序改变成right,把当前结果放到b中暂存。
直到再次遇到加、减、)右括号时,意味计算顺序复位成left,先把b中的暂存结果全部合并后,再继续算a中的剩余数据
最后合并成一个结果值。
Ⅲ java 关于逆波兰表达式的两个题
import java.util.Stack;
/**
* @author wengsh
* @date 2010-6-3 用 输入 (6+5)*(5+5) 测试一下
*/
public class MyDemo {
public static void main(String[] a) {
Stack<Character> stack = new Stack<Character>();
StringBuffer sb = new StringBuffer();
if (a.length < 1) {
System.out.println("参数长度不够");
} else {
String s = a[0].trim();
char[] c = s.toCharArray();
try {
for (int i = 0; i < c.length; i++) {
int priority = getPriority(c[i]);
if (priority == -1) { // 如果是数字
sb.append(c[i]); // 输出数字或都字母
} else {
if (stack.isEmpty()) {// 当栈为空时
stack.push(c[i]); // 把字符压入栈
} else {// 当栈为不空时
if (priority == -2) { // 如果是 ')'
while (!stack.isEmpty()
&& getPriority(stack.peek()) != 8) {
sb.append(stack.pop());// 把'('之上的字符弹出栈并输出
}
stack.pop(); // 栈弹出'('
} else {
// 当要压入栈的字符的优先级小于 等于栈顶字符的优先级且栈顶字符不为'('时
while (!stack.isEmpty()
&& priority <= getPriority(stack.peek())
&& getPriority(stack.peek()) != 8) {
sb.append(stack.pop()); // 弹出栈顶字符并输出
}
stack.push(c[i]);// 将此时的字符压入栈顶
}
}
}
}
// 读到输入末尾
while (!stack.isEmpty()) {
sb.append(stack.pop()); // 弹出栈中所有元素并输出
}
System.out.println(sb); // 结果 65+55+*
System.out.println(calstack(sb.toString()));//结果 110.0
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 获得字符串优先级如果字符不在给定的范围内,则抛出异常,数字和字母的优先级最低
*
* @param c
* @return
* @throws Exception
*/
public static int getPriority(char c) throws Exception {
int priority = -1;
if (Character.isDigit(c)) {
priority = -1;
} else if (Character.isLetter(c)) {
priority = 0;
} else {
if (c == '(') {
priority = 8;
} else if (c == '*' || c == '/') {
priority = 5;
} else if (c == '+' || c == '-') {
priority = 4;
} else if (c == ')') {
priority = -2;
} else {
throw new Exception("无法解析的前序表达式: " + c);
}
}
return priority;
}
/**
* 计算栈结果
* 6+5*8
* @param s
* @return
*/
public static float calstack(String s) {
Stack<Float> stack = new Stack<Float>();
char[] c = s.toCharArray();
try {
for (int i = 0; i < c.length; i++) {
int priority = getPriority(c[i]);
if (priority == -1) {
stack.push(new Float(Character.digit(c[i], 10)));
} else {
stack.push(cal(stack.pop(), stack.pop(), c[i]));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return stack.pop();
}
/**
* a b 运算
* @param a
* @param b
* @param opertor
* @return
*/
public static float cal(float a, float b, char opertor) {
float r = 0;
switch (opertor) {
case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
r = a * b;
break;
case '/':
r = a / b;
break;
}
return r;
}
}
Ⅳ 逆波兰表示法的实际意义
当有操作符时就计算,因此,表达式并不是从右至左整体计算而是每次由中心向外计算一部分,这样在复杂运算中就很少导致操作符错误。
堆栈自动记录中间结果,这就是为什么逆波兰计算器能容易对任意复杂的表达式求值。与普通科学计算器不同,它对表达式的复杂性没有限制。
逆波兰表达式中不需要括号,用户只需按照表达式顺序求值,让堆栈自动记录中间结果;同样的,也不需要指定操作符的优先级。
逆波兰计算器中,没有“等号”键用于开始计算。
逆波兰计算器需要“确认”键用于区分两个相邻的操作数。
机器状态永远是一个堆栈状态,堆栈里是需要运算的操作数,栈内不会有操作符。
教育意义上,逆波兰计算器的使用者必须懂得要计算的表达式的含义。
目前逆波兰的实现有:
任何基于栈的程序语言:
Forth
Factor语言
PostScript语言。
Windows下逆波兰计算器
Windows XP下的Microsoft PowerToy calculator
手机逆波兰计算器开源的JAVA计算器
Palm PDA下的逆波兰计算器
Mac OS X计算器
Mac OS X和iPhone下的逆波兰计算器
Unix下的计算程序dc
交互式JavaScript的逆波兰计算器:
rpn-calculator
Wikibooks:Ada Programming/Mathematical calculations (Ada语言中的逆波兰计算器)
Emacs的lisp lib包: calc
基于GTK+的galculator
表达式转换
Ⅳ 表达式求值 逆波兰表达式算法 java版
表达式求值 逆波兰表达式算法 如下:
import java.util.ArrayList;
import java.util.List;
public class MyStack {
private List<String> l;
private int size;
public String top;
public MyStack() {
l = new ArrayList<String>();
size = 0;
top = null;
}
public int size() {
return size;
}
public void push(String s) {
l.add(s);
top = s;
size++;
}
public String pop() {
String s = l.get(size - 1);
l.remove(size - 1);
size--;
top = size == 0 ? null : l.get(size - 1);
return s;
}
}
import java.util.ArrayList;
import java.util.List;
public class Nbl {
private static MyStack ms1 = new MyStack();//生成逆波兰表达式的栈
private static MyStack ms2 = new MyStack();//运算栈
/**
* 将字符串转换为中序表达式
*/
public static List<String> zb(String s) {
List<String> ls = new ArrayList<String>();//存储中序表达式
int i = 0;
String str;
char c;
do {
if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {
ls.add("" + c);
i++;
} else {
str = "";
while (i < s.length() && (c = s.charAt(i)) >= 48
&& (c = s.charAt(i)) <= 57) {
str += c;
i++;
}
ls.add(str);
}
} while (i < s.length());
return ls;
}
/**
* 将中序表达式转换为逆波兰表达式
*/
public static List<String> parse(List<String> ls) {
List<String> lss = new ArrayList<String>();
for (String ss : ls) {
if (ss.matches("\d+")) {
lss.add(ss);
} else if (ss.equals("(")) {
ms1.push(ss);
} else if (ss.equals(")")) {
while (!ms1.top.equals("(")) {
lss.add(ms1.pop());
}
ms1.pop();
} else {
while (ms1.size() != 0 && getValue(ms1.top) >= getValue(ss)) {
lss.add(ms1.pop());
}
ms1.push(ss);
}
}
while (ms1.size() != 0) {
lss.add(ms1.pop());
}
return lss;
}
/**
* 对逆波兰表达式进行求值
*/
public static int jisuan(List<String> ls) {
for (String s : ls) {
if (s.matches("\d+")) {
ms2.push(s);
} else {
int b = Integer.parseInt(ms2.pop());
int a = Integer.parseInt(ms2.pop());
if (s.equals("+")) {
a = a + b;
} else if (s.equals("-")) {
a = a - b;
} else if (s.equals("*")) {
a = a * b;
} else if (s.equals("\")) {
a = a / b;
}
ms2.push("" + a);
}
}
return Integer.parseInt(ms2.pop());
}
/**
* 获取运算符优先级
* +,-为1 *,/为2 ()为0
*/
public static int getValue(String s) {
if (s.equals("+")) {
return 1;
} else if (s.equals("-")) {
return 1;
} else if (s.equals("*")) {
return 2;
} else if (s.equals("\")) {
return 2;
}
return 0;
}
public static void main(String[] args) {
System.out.println(jisuan(parse(zb("0-8+((1+2)*4)-3+(2*7-2+2)"))));
}
}
Ⅵ 用Java写的计算器的程序!不需要界面!
用java写的计算器的程序,主要是通过控制台输入,主要方法是使用scanner类来接收用户从键盘输入的一个算式,通过分解算式,存入两个字符串,判断中间的的符号,进行相应计算,如下代码:
System.out.println("-----------------------------------");
System.out.println("请输入一个算术表达式,如:45*23");
Scannerin=newScanner(System.in);//接收用户从键盘输入的字符
Stringstr=in.nextLine();
StringBufferbuffer=newStringBuffer();//保存左侧的数字
StringBufferbuffer1=newStringBuffer();//保存右侧的数字
chart='';//保存运算符
for(inti=0;i<str.length();i++){
if(str.charAt(i)=='+'||str.charAt(i)=='-'
||str.charAt(i)=='*'||str.charAt(i)=='/'){
t=str.charAt(i);//识别是什么运算符
for(intj=i+1;j<str.length();j++){
buffer1.append(str.charAt(j));
}
break;
}else{
buffer.append(str.charAt(i));
}
}
Stringc=buffer.toString();
Stringd=buffer1.toString();
doublea=Double.parseDouble(c);
doubleb=Double.parseDouble(d);
doublesum=0;
if(t=='+'){
sum=a+b;
}
if(t=='-'){
sum=a-b;
}
if(t=='*'){
sum=a*b;
}
if(t=='/'){
sum=a/b;
}
System.out.println("程序运算...");
System.out.println(c+t+d+"="+sum);
System.out.print("-----------------------------------");
运行结果如下:
Ⅶ java数据结构对逆波兰式进行求值运算,并将结果进行输出
ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
Ⅷ 求一个java逆波兰算法的代码,要带输入框.就是可以根据输入框的内容用逆波兰算法求出答案.
已发送。多加点分哈
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
//栈类
class Stacks {
private LinkedList list = new LinkedList();
int top = -1;
public void push(Object value) {
top++;
list.addFirst(value);
}
public Object pop() {
Object temp = list.getFirst();
top--;
list.removeFirst();
return temp;
}
public Object top() {
return list.getFirst();
}
}
class Expression {
private ArrayList expression = new ArrayList();// 存储中序表达式
private ArrayList right = new ArrayList();// 存储右序表达式
private String result;// 结果
// 依据输入信息创建对象,将数值与操作符放入ArrayList中
Expression(String input) {
StringTokenizer st = new StringTokenizer(input, "+-*/()", true);
while (st.hasMoreElements()) {
String s = st.nextToken();
expression.add(s);
}
}
// 将中序表达式转换为右序表达式
private void toRight() {
Stacks aStack = new Stacks();
String operator;
int position = 0;
while (true) {
if (Calculate.isOperator((String) expression.get(position))) {
if (aStack.top == -1
|| ((String) expression.get(position)).equals("(")) {
aStack.push(expression.get(position));
} else {
if (((String) expression.get(position)).equals(")")) {
while (true) {
if (aStack.top != -1
&& !((String) aStack.top()).equals("(")) {
operator = (String) aStack.pop();
right.add(operator);
} else {
if (aStack.top != -1)
aStack.pop();
break;
}
}
} else {
while (true) {
if (aStack.top != -1
&& Calculate.priority((String) expression
.get(position)) <= Calculate
.priority((String) aStack.top())) {
operator = (String) aStack.pop();
if (!operator.equals("("))
right.add(operator);
} else {
break;
}
}
aStack.push(expression.get(position));
}
}
} else
right.add(expression.get(position));
position++;
if (position >= expression.size())
break;
}
while (aStack.top != -1) {
operator = (String) aStack.pop();
if (!operator.equals("("))
right.add(operator);
}
}
// 对右序表达式进行求值
String getResult() {
String str = "";
this.toRight();
for (int i = 0; i < right.size(); i++) {
System.out.println(right.get(i));
}
Stacks aStack = new Stacks();
String op1, op2, is = null;
Iterator it = right.iterator();
while (it.hasNext()) {
is = (String) it.next();
if (Calculate.isOperator(is)) {
op1 = (String) aStack.pop();
op2 = (String) aStack.pop();
aStack.push(Calculate.twoResult(is, op1, op2));
} else
aStack.push(is);
}
result = (String) aStack.pop();
it = expression.iterator();
while (it.hasNext()) {
str += (String) it.next();
}
str += "\n=" + result;
return str;
}
}
class Calculate {
// 判断是否为操作符号
public static boolean isOperator(String operator) {
if (operator.equals("+") || operator.equals("-")
|| operator.equals("*") || operator.equals("/")
|| operator.equals("(") || operator.equals(")"))
return true;
else
return false;
}
// 设置操作符号的优先级别
public static int priority(String operator) {
if (operator.equals("+") || operator.equals("-"))
return 1;
else if (operator.equals("*") || operator.equals("/"))
return 2;
else
return 0;
}
// 做2值之间的计算
public static String twoResult(String operator, String a, String b) {
try {
String op = operator;
String rs = new String();
double x = Double.parseDouble(b);
double y = Double.parseDouble(a);
double z = 0;
if (op.equals("+"))
z = x + y;
else if (op.equals("-"))
z = x - y;
else if (op.equals("*"))
z = x * y;
else if (op.equals("/"))
z = x / y;
else
z = 0;
return rs + z;
} catch (NumberFormatException e) {
System.out.println("input has something wrong!");
return "Error";
}
}
}
public class Test extends JFrame {
JTextField exprss;
JLabel rlt;
JButton button;
public Test() {
this.setSize(500, 200);// 设置大小
this.setTitle("第一个JFrame的窗体!"); // 设置标题处的文字
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 窗体关闭时的操作 退出程序
double width = Toolkit.getDefaultToolkit().getScreenSize().width; // 得到当前屏幕分辨率的高
double height = Toolkit.getDefaultToolkit().getScreenSize().height;// 得到当前屏幕分辨率的宽
this.setLocation((int) (width - this.getWidth()) / 2,
(int) (height - this.getHeight()) / 2); // 设置窗体居中显示
this.setResizable(false);// 禁用最大化按钮
JPanel contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(new FlowLayout());
exprss = new JTextField(10);
rlt = new JLabel();
rlt.setSize(200, 20);
button = new JButton("计算");
contentPane.add(exprss);
contentPane.add(button);
contentPane.add(rlt);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
String input = exprss.getText().trim();
Expression boya = new Expression(input);
String str = boya.getResult();
rlt.setText(str);
} catch (Exception ex) {
rlt.setText("Wrong input!!!");
}
}
});
}
public static void main(String avg[]) {
Test test = new Test();
test.setVisible(true);
}
}
Ⅸ 怎样用JAVA写出逆波兰表达式求值部分的源代码(提供代码框架)
下面的代码是用来计算表达式的,看看是不是你要的
public class OPNode {
char op;// 运算符号
int level;// 优先级
//设置优先级
public OPNode(String op) {
this.op = op.charAt(0);
if (op.equals("+") || op.equals("-")) {
this.level = 1;
} else if (op.equals("*") || op.equals("/")) {
this.level = 2;
} else if (op.equals("(")) {
this.level = -3;
} else {
this.level = -1;
}
}
}
//主类
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class OPText {
public static void main(String[] args) {
String expression = "2+2+(8-2)/3";// 要计算的表达式
List list = new LinkedList();
//正则式
Pattern entryOfExpression = Pattern
.compile("[0-9]+(\\.[0-9]+)?|\\(|\\)|\\+|-|\\*|/");
Deque stack = new LinkedList();//栈
Matcher m = entryOfExpression.matcher(expression);
while (m.find()) {
//提取语素
String nodeString = expression.substring(m.start(), m.end());
if (nodeString.matches("[0-9].*")) {
list.add(Double.valueOf(nodeString));//如果是数字直接送入列表
} else {
OPNode opn = new OPNode(nodeString);//如果是运算符
int peekLevel = (stack.peek() == null) ? 0 : ((OPNode) stack
.peek()).level;
if (opn.level >=peekLevel) {
stack.push(opn);//新的运算符比旧的优先级别高则入栈
} else {
if (opn.level == -1) {
OPNode temp = (OPNode) stack.pop();
while (temp.level != -3) {//如果为"("则一直出栈一直到")"
list.add(temp);
System.out.println(nodeString);
temp = (OPNode) stack.pop();
}
} else if (opn.level == -3) {
stack.push(opn);
} else {//如果新运算符比栈顶运算符底则一直出栈
OPNode temp = (OPNode) stack.pop();
while (temp.level > opn.level) {
list.add(temp);
if (stack.isEmpty()) {
break;
}
temp = (OPNode) stack.pop();
}
stack.push(opn);
}
}
}
}
OPNode temp = null;
while (!stack.isEmpty()) {
temp = (OPNode) stack.pop();
list.add(temp);
}//后续表达式计算
stack.clear();
for (Object o : list) {
if (o instanceof Double) {
stack.push(o);//为数字入栈
} else {
double op2 = ((Double) stack.pop()).doubleValue();
double op1 = ((Double) stack.pop()).doubleValue();
switch (((OPNode) o).op) {
case '+':
stack.push(op1 + op2);
break;
case '-':
stack.push(op1 - op2);
break;
case '*':
stack.push(op1 * op2);
break;
case '/':
stack.push(op1 / op2);
break;
}
}
}
System.out.println("结果为:" + stack.pop());
}
}
呃,太晚了,没心思去改了
明天再说
Ⅹ java 设计算法,计算用后缀表示法表示的算术表达式的值。
你好!
后缀表达式也称逆波兰表达式,其优点就在于可以方便的用栈实现表达式的值的计算。和你说一下思路吧:
·从头读入表达式
·如果遇到数则将其压入栈
·如果遇到运算符,从栈中弹出栈顶连个数,实行相应运算,将结果压入栈中
·直到表达式尾,此时栈中应该只有一个元素,即运算结果
·Over
如果对你有帮助,望采纳。