Ⅰ 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
如果對你有幫助,望採納。