import java.util.Collections;
汕頭網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),汕頭網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為汕頭上1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的汕頭做網(wǎng)站的公司定做!
import java.util.Stack;
public class Calculator {
private StackString postfixStack = new StackString();//后綴式棧
private StackCharacter opStack = new StackCharacter();//運算符棧
private int [] operatPriority = new int[] {0,3,2,1,-1,1,0,2};//運用運算符ASCII碼-40做索引的運算符優(yōu)先級
public static void main(String[] args) {
System.out.println(5+12*(3+5)/7.0);
Calculator cal = new Calculator();
String s = "5+12*(3+5)/7";
double result = cal.calculate(s);
System.out.println(result);
}
/**
* 按照給定的表達(dá)式計算
* @param expression 要計算的表達(dá)式例如:5+12*(3+5)/7
* @return
*/
public double calculate(String expression) {
StackString resultStack = new StackString();
prepare(expression);
Collections.reverse(postfixStack);//將后綴式棧反轉(zhuǎn)
String firstValue ,secondValue,currentValue;//參與計算的第一個值,第二個值和算術(shù)運算符
while(!postfixStack.isEmpty()) {
currentValue = postfixStack.pop();
if(!isOperator(currentValue.charAt(0))) {//如果不是運算符則存入操作數(shù)棧中
resultStack.push(currentValue);
} else {//如果是運算符則從操作數(shù)棧中取兩個值和該數(shù)值一起參與運算
secondValue = resultStack.pop();
firstValue = resultStack.pop();
String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
resultStack.push(tempResult);
}
}
return Double.valueOf(resultStack.pop());
}
/**
* 數(shù)據(jù)準(zhǔn)備階段將表達(dá)式轉(zhuǎn)換成為后綴式棧
* @param expression
*/
private void prepare(String expression) {
opStack.push(',');//運算符放入棧底元素逗號,此符號優(yōu)先級最低
char[] arr = expression.toCharArray();
int currentIndex = 0;//當(dāng)前字符的位置
int count = 0;//上次算術(shù)運算符到本次算術(shù)運算符的字符的長度便于或者之間的數(shù)值
char currentOp ,peekOp;//當(dāng)前操作符和棧頂操作符
for(int i=0;iarr.length;i++) {
currentOp = arr[i];
if(isOperator(currentOp)) {//如果當(dāng)前字符是運算符
if(count 0) {
postfixStack.push(new String(arr,currentIndex,count));//取兩個運算符之間的數(shù)字
}
peekOp = opStack.peek();
if(currentOp == ')') {//遇到反括號則將運算符棧中的元素移除到后綴式棧中直到遇到左括號
while(opStack.peek() != '(') {
postfixStack.push(String.valueOf(opStack.pop()));
}
opStack.pop();
} else {
while(currentOp != '(' peekOp != ',' compare(currentOp,peekOp) ) {
postfixStack.push(String.valueOf(opStack.pop()));
peekOp = opStack.peek();
}
opStack.push(currentOp);
}
count = 0;
currentIndex = i+1;
} else {
count++;
}
}
if(count 1 || (count == 1 !isOperator(arr[currentIndex]))) {//最后一個字符不是括號或者其他運算符的則加入后綴式棧中
postfixStack.push(new String(arr,currentIndex,count));
}
while(opStack.peek() != ',') {
postfixStack.push(String.valueOf( opStack.pop()));//將操作符棧中的剩余的元素添加到后綴式棧中
}
}
/**
* 判斷是否為算術(shù)符號
* @param c
* @return
*/
private boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' ||c == ')';
}
/**
* 利用ASCII碼-40做下標(biāo)去算術(shù)符號優(yōu)先級
* @param cur
* @param peek
* @return
*/
public boolean compare(char cur,char peek) {// 如果是peek優(yōu)先級高于cur,返回true,默認(rèn)都是peek優(yōu)先級要低
boolean result = false;
if(operatPriority[(peek)-40] = operatPriority[(cur) - 40]) {
result = true;
}
return result;
}
/**
* 按照給定的算術(shù)運算符做計算
* @param firstValue
* @param secondValue
* @param currentOp
* @return
*/
private String calculate(String firstValue,String secondValue,char currentOp) {
String result = "";
switch(currentOp) {
case '+':
result = String.valueOf(ArithHelper.add(firstValue, secondValue));
break;
case '-':
result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
break;
case '*':
result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
break;
case '/':
result = String.valueOf(ArithHelper.div(firstValue, secondValue));
break;
}
return result;
}
}
public class ArithHelper {
// 默認(rèn)除法運算精度
private static final int DEF_DIV_SCALE = 16;
// 這個類不能實例化
private ArithHelper() {
}
/**
* 提供精確的加法運算。
*
* @param v1 被加數(shù)
* @param v2 加數(shù)
* @return 兩個參數(shù)的和
*/
public static double add(double v1, double v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
public static double add(String v1, String v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
return b1.add(b2).doubleValue();
}
/**
* 提供精確的減法運算。
*
* @param v1 被減數(shù)
* @param v2 減數(shù)
* @return 兩個參數(shù)的差
*/
public static double sub(double v1, double v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
public static double sub(String v1, String v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
return b1.subtract(b2).doubleValue();
}
/**
* 提供精確的乘法運算。
*
* @param v1
* 被乘數(shù)
* @param v2
* 乘數(shù)
* @return 兩個參數(shù)的積
*/
public static double mul(double v1, double v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
public static double mul(String v1, String v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相對)精確的除法運算,當(dāng)發(fā)生除不盡的情況時,精確到 小數(shù)點以后10位,以后的數(shù)字四舍五入。
*
* @param v1
* 被除數(shù)
* @param v2
* 除數(shù)
* @return 兩個參數(shù)的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
public static double div(String v1, String v2) {
java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
return b1.divide(b2, DEF_DIV_SCALE, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供(相對)精確的除法運算。當(dāng)發(fā)生除不盡的情況時,由scale參數(shù)指 定精度,以后的數(shù)字四舍五入。
*
* @param v1 被除數(shù)
* @param v2 除數(shù)
* @param scale 表示表示需要精確到小數(shù)點以后幾位。
* @return 兩個參數(shù)的商
*/
public static double div(double v1, double v2, int scale) {
if (scale 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精確的小數(shù)位四舍五入處理。
*
* @param v 需要四舍五入的數(shù)字
* @param scale 小數(shù)點后保留幾位
* @return 四舍五入后的結(jié)果
*/
public static double round(double v, int scale) {
if (scale 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
java.math.BigDecimal b = new java.math.BigDecimal(Double.toString(v));
java.math.BigDecimal one = new java.math.BigDecimal("1");
return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static double round(String v, int scale) {
if (scale 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
java.math.BigDecimal b = new java.math.BigDecimal(v);
java.math.BigDecimal one = new java.math.BigDecimal("1");
return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
import java.util.ArrayList;
import java.util.Stack;
/**itjob
*
* @author yhh
*
*/
public class Calculate {
/**
* 將字符串轉(zhuǎn)化成List
* @param str
* @return
*/
public ArrayListString getStringList(String str){
ArrayListString result = new ArrayListString();
String num = "";
for (int i = 0; i str.length(); i++) {
if(Character.isDigit(str.charAt(i))){
num = num + str.charAt(i);
}else{
if(num != ""){
result.add(num);
}
result.add(str.charAt(i) + "");
num = "";
}
}
if(num != ""){
result.add(num);
}
return result;
}
/**
* 將中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式
* @param inOrderList
* @return
*/
public ArrayListString getPostOrder(ArrayListString inOrderList){
ArrayListString result = new ArrayListString();
StackString stack = new StackString();
for (int i = 0; i inOrderList.size(); i++) {
if(Character.isDigit(inOrderList.get(i).charAt(0))){
result.add(inOrderList.get(i));
}else{
switch (inOrderList.get(i).charAt(0)) {
case '(':
stack.push(inOrderList.get(i));
break;
case ')':
while (!stack.peek().equals("(")) {
result.add(stack.pop());
}
stack.pop();
break;
default:
while (!stack.isEmpty() compare(stack.peek(), inOrderList.get(i))){
result.add(stack.pop());
}
stack.push(inOrderList.get(i));
break;
}
}
}
while(!stack.isEmpty()){
result.add(stack.pop());
}
return result;
}
/**
* 計算后綴表達(dá)式
* @param postOrder
* @return
*/
public Integer calculate(ArrayListString postOrder){
Stack stack = new Stack();
for (int i = 0; i postOrder.size(); i++) {
if(Character.isDigit(postOrder.get(i).charAt(0))){
stack.push(Integer.parseInt(postOrder.get(i)));
}else{
Integer back = (Integer)stack.pop();
Integer front = (Integer)stack.pop();
Integer res = 0;
switch (postOrder.get(i).charAt(0)) {
case '+':
res = front + back;
break;
case '-':
res = front - back;
break;
case '*':
res = front * back;
break;
case '/':
res = front / back;
break;
}
stack.push(res);
}
}
return (Integer)stack.pop();
}
/**
* 比較運算符等級
* @param peek
* @param cur
* @return
*/
public static boolean compare(String peek, String cur){
if("*".equals(peek) ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){
return true;
}else if("/".equals(peek) ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur))){
return true;
}else if("+".equals(peek) ("+".equals(cur) || "-".equals(cur))){
return true;
}else if("-".equals(peek) ("+".equals(cur) || "-".equals(cur))){
return true;
}
return false;
}
public static void main(String[] args) {
Calculate calculate = new Calculate();
String s = "12+(23*3-56+7)*(2+90)/2";
ArrayList result = calculate.getStringList(s); //String轉(zhuǎn)換為List
result = calculate.getPostOrder(result); //中綴變后綴
int i = calculate.calculate(result); //計算
System.out.println(i);
}
}
Java是面向表達(dá)式的語言,Java中一個簡單表達(dá)式可以是下面任意一種:● 常量:7、false?!?單引號括起來的字符字面常量:'A'、'3'。● 雙引號括起來的字符串字面常量:"foo"、"Java"?!?任何正確聲明的變量名:myString、x?!?任何用Java二元運算符(本章稍后將詳細(xì)討論)連接起來的兩個上述類型的表達(dá)式:x+2?!?任何用Java一元運算符(本章稍后將詳細(xì)討論)修飾的單個上述類型的表達(dá)式:i++?!?任何用小括號括起來的上述類型的表達(dá)式:(x+2)。以及另外一些與本書后面將要學(xué)到的對象有關(guān)的表達(dá)式類型。無論多么復(fù)雜的表達(dá)式都可以由不同類型的簡單表達(dá)式和括號嵌套組合而成,例如:((((4/x) + y) * 7) + z)。2.9.1 算術(shù)運算符 Java語言提供了許多基本的算術(shù)運算符,如表2-1所示。表2-1 Java算術(shù)運算符運算符描 述+加法-減法*乘法/除法%求余(%左邊的操作數(shù)除以右邊的
操作數(shù)所得到的余數(shù),例如10%3=1)+和-運算符也可作為一元運算符用于表示正負(fù)數(shù):-3.7、+42。除了簡單賦值運算符=,還有許多特定的復(fù)合賦值運算符,這些運算符將變量賦值和算術(shù)操作合并在一起,如表2-2所示。表2-2 Java復(fù)合賦值運算符運算符描 述+=a+=b等價于a=a+b-=a-=b等價于a=a-b*=a*=b等價于a=a*b/=a/=b等價于a=a/b%=a%=b等價于a=a%b最后要介紹的兩個算術(shù)運算符是一元遞增運算符(++)和一元遞減運算符(--),用于將整數(shù)變量的值加1或減1,或者將浮點數(shù)變量的值加1.0或減1.0。稱它們?yōu)橐辉\算符是因為它們用于單個變量,而前面討論的二元運算符則連接兩個表達(dá)式的值。一元遞增運算符和一元遞減運算符也可用于將字符變量在Unicode序列中向前或向后移動一個字符位置。例如,在下面的代碼片段中,字符變量c的值從'e'遞增為'f':遞增和遞減運算符可以以前綴或者后綴方式使用。如果運算符放在操作數(shù)之前(前綴模式),變量的遞增或遞減操作將在更新后的變量值被用于任何由它構(gòu)成的賦值操作之前執(zhí)行。例如,考慮下面的使用前綴遞增運算符的代碼片段,假設(shè)a和b在程序前面已經(jīng)聲明為int變量:上述代碼執(zhí)行后,變量a的值是2,變量b的值也是2。這是因為在第二行中變量a的遞增(從1到2)發(fā)生在它的值賦給b之前。因此這行代碼在邏輯上等價于下面兩行代碼: 另一方面,如果運算符放在操作數(shù)之后(后綴模式),遞增或遞減操作發(fā)生在原來的變量值被用于任何由它構(gòu)成的賦值操作之后??匆幌乱院缶Y方式使用遞增運算符的相同代碼片段:上述代碼執(zhí)行后,變量b的值是1,而變量a的值是2。這是因為在第二行中變量a的遞增(從1到2)發(fā)生在它的值賦給b之后。因此這行代碼在邏輯上等價于下面兩行代碼:下面是一個稍微復(fù)雜一點例子,請閱讀附加的注釋以確保你能夠明白x最終是如何被賦值為10的:稍后將會看到,遞增和遞減運算符通常和循環(huán)一起使用。2.9.2 關(guān)系和邏輯運算符邏輯表達(dá)式以指定的方式比較兩個(簡單或者復(fù)雜)表達(dá)式exp1和exp2,決議出一個boolean值true或者false。 Java提供了表2-3所示的關(guān)系運算符來創(chuàng)建邏輯表達(dá)式。表2-3 Java關(guān)系運算符運算符描 述exp1==exp2如果exp1等于exp2,值為true(注意使用雙等號測試相等性)exp1exp2如果exp1大于exp2,值為trueexp1=exp2如果exp1大于等于exp2,值為trueexp1exp2如果exp1小于exp2,值為trueexp1修飾邏輯表達(dá)式的邏輯運算符。表2-4列出了最常用的邏輯運算符。表2-4 Java邏輯運算符運算符描 述exp1exp2邏輯“與”,僅當(dāng)exp1和exp2都為true時復(fù)合表達(dá)式值為trueexp1||exp2邏輯“或”,exp1或exp2值為true時復(fù)合表達(dá)式值為true!exp邏輯“非”,將邏輯表達(dá)式的值從true切換到false,反之亦然下面這個例子用邏輯“與”運算符來編程實現(xiàn)邏輯表達(dá)式“如果x大于2.0且y不等于4.0”:邏輯表達(dá)式常用于流程控制結(jié)構(gòu),本章稍后將進(jìn)行討論。2.9.3 表達(dá)式求值和運算符優(yōu)先級如同本章前面提到的那樣,任何復(fù)雜的表達(dá)式都可以用分層嵌套的小括號構(gòu)成,例如(((8 * (y + z)) + y) x)。編譯器通常按照從內(nèi)到外,從左到右的順序?qū)@樣的表達(dá)式求值。假設(shè)x、y、z按照下面的方式聲明并初始化:下面的賦值語句右邊的表達(dá)式:將像下面這樣逐步求值:沒有小括號時,根據(jù)運算符用于表達(dá)式求值的順序,某些運算符具有高于其他運算符的優(yōu)先級。例如,乘除法先于加減法執(zhí)行。通過使用小括號可以強制改變運算符的優(yōu)先級,括號內(nèi)的運算符比括號外的先執(zhí)行??紤]下面的代碼片段:代碼的第一行沒有使用括號,乘法操作比加法操作先執(zhí)行,因此整個表達(dá)式的值為2+12=14,就像我們將表達(dá)式明確地寫成2+(3*4)一樣,當(dāng)然這樣做沒有必要。 在代碼的第二行,括號被明確地放在操作2+3兩邊,因此加法操作將首先執(zhí)行,然后求和結(jié)果乘以4作為整個表達(dá)式的值,即5*4=20?;氐角懊娴睦幼⒁獾胶?=運算符優(yōu)先級高于運算符,因此可以去掉嵌套的括號而變成下面這樣:然而,額外的括號并不會對代碼造成傷害,事實上它可以使表達(dá)式的目的更加清楚。2.9.4 表達(dá)式類型表達(dá)式類型是表達(dá)式最終求值結(jié)果的Java類型。例如給定下面的代碼片段:表達(dá)式(x 2.0) (y != 4.0)求值結(jié)果為true,因此表達(dá)式(x 2.0) (y != 4.0)稱為boolean型表達(dá)式。在下面的代碼片段中:表達(dá)式((8 * (y + z)) + y) * x求值結(jié)果為42,因此表達(dá)式((8 * (y + z)) + y) * x稱為整型表達(dá)式。
Java表達(dá)式是變量、常量、運算符、方法調(diào)用的序列,它執(zhí)行指定的計算并返回某個確定的值。
其中,運算符按操作數(shù)的數(shù)目:有一元運算符(++、--)、二元運算符(+、-、等等)和三元運算符(?:),它們分別對應(yīng)一到三個操作數(shù)。
表達(dá)式一般按運算符來分:
算術(shù)表達(dá)式(float x=8.3f、i++)、
關(guān)系表達(dá)式(37、37)、
布爾邏輯表達(dá)式((54)true、!false)、
位運算表達(dá)式(a=34^3)、
賦值表達(dá)式、
條件表達(dá)式(b=10089?a=ture:a=false)
以及復(fù)合表達(dá)式。
還有一種叫“表達(dá)式語句”,就是在表達(dá)式后加上分號作為語句來使用。(int i=123;)