20172312『Java程序設計』課程 結對編程練習_四則運算第二周階段總結
20172312『Java程序設計』課程 結對編程練習_四則運算第二周階段總結
結對夥伴
-
學號 :20172315 20172318
-
姓名 :胡智韜 陸大嶽
- 夥伴第一周博客地址:
-
對結對夥伴的評價:這倆人一開始各編各的還好,到後面就開始吵,從頭吵到尾,陸大胖,胡誌汪,還好到最後是把代碼敲出來了,不容易不容易。
小組結對編程的照片(QQ群截圖)
項目中自己負責的部分
代碼的綜合整理,錯誤查找,合並以及博客的撰寫。
個人貢獻度劃分
彭霖:胡智韜:陸大嶽=3:3:4
相關過程的截圖
-
生成題目類驅動類的部分截圖
-
最後運行結果截圖
關鍵代碼解釋
1.運行分數計算的分數計算類
import chap4.RationalNumber;
import java.util.Stack;
import java.util.regex.Pattern;/**
* 將中綴表達式字符串轉換為後綴表達式
*/
public class StringToArithmetic {
// 默認構造
public StringToArithmetic() {}
// 將中綴表達式字符串計算得到結果
public static double stringToArithmetic(String string) {
return suffixToArithmetic(infixToSuffix(string));
}// 將中綴表達式轉換為後綴表達式
public static String infixToSuffix(String exp) {
// 創建操作符堆棧
Stack<Character> s = new Stack<Character>();
// 要輸出的後綴表達式字符串
String suffix = "";
int length = exp.length(); // 輸入的中綴表達式的長度
for (int i = 0; i < length; i++) {
char temp;// 臨時字符變量
// 獲取該中綴表達式的每一個字符並進行判斷
char ch = exp.charAt(i);
switch (ch) {
// 忽略空格
case ‘ ‘:
break;
// 如果是左括號直接壓入堆棧
case ‘(‘:
s.push(ch);
break;// 碰到‘+‘ ‘-‘,將棧中的所有運算符全部彈出去,直至碰到左括號為止,輸出到隊列中去
case ‘+‘:
case ‘-‘:
while (s.size() != 0) {
temp = s.pop();
if (temp == ‘(‘) {
// 重新將左括號放回堆棧,終止循環
s.push(‘(‘);
break;
}
suffix += temp;
}
// 沒有進入循環說明是當前為第一次進入或者其他前面運算都有括號等情況導致棧已經為空,此時需要將符號進棧
s.push(ch);
break;// 如果是乘號或者除號,則彈出所有序列,直到碰到加好、減號、左括號為止,最後將該操作符壓入堆棧
case ‘ב:
case ‘/‘:
case ‘÷‘:
while (s.size() != 0) {
temp = s.pop();
// 只有比當前優先級高的或者相等的才會彈出到輸出隊列,遇到加減左括號,直接停止當前循環
if (temp == ‘+‘ || temp == ‘-‘ || temp == ‘(‘) {
s.push(temp);
break;
} else {
suffix += temp;
}
}// 沒有進入循環說明是當前為第一次進入或者其他前面運算都有括號等情況導致棧已經為空,此時需要將符號進棧
s.push(ch);
break;// 如果碰到的是右括號,則距離棧頂的第一個左括號上面的所有運算符彈出棧並拋棄左括號
case ‘)‘:
// 這裏假設一定會遇到左括號了,此為自己改進版,已經驗證可以過
// while ((temp = s.pop()) != ‘(‘) {
// suffix += temp;
// }
while (!s.isEmpty()) {
temp = s.pop();
if (temp == ‘(‘) {
break;
} else {
suffix += temp;
}
}
break;
// 默認情況,如果讀取到的是數字,則直接送至輸出序列
default:
suffix += ch;
break;
}}
while (s.size() != 0) {
suffix += s.pop();
}
//
return suffix;
}
public static double suffixToArithmetic(String exp) {
String[] strings = exp.split("");
Stack<Double> stack = new Stack<Double>();
for (int i = 0; i < strings.length; i++) {
Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)");
// 這裏最好是進行判斷徹底消除空格,在該數組的第一位為一個隱形的空格,這裏一定要註意在使用exp.split("")剔除空白""
// 由於使用的是""截取導致在數組第一位上面的值為空白
if (strings[i].equals("")) {
continue;
}
// 如果遇到了數字則直接進棧
if (pattern.matcher(strings[i]).matches()) {
stack.push(Double.parseDouble(strings[i]));
}
// 如果是運算符,則彈出棧頂的兩個數進行計算
else {
// !!!這裏需要註意,先彈出的那個數其實是第二個計算數值,這裏記作y!
// 自己書寫的時候出錯
double y = stack.pop();
double x = stack.pop();
// 將運算結果重新壓棧
stack.push(calculate(x, y, strings[i]));
}
}
// 彈出棧頂元素就是最終結果
return stack.pop();
}
private static Double calculate(double x, double y, String string) {
// TODO Auto-generated method stub
// 其實使用case邏輯也可以
if (string.trim().equals("+")) {
return x + y;
}
if (string.trim().equals("-")) {
return x - y;
}
if (string.trim().equals("×")) {
return x * y;
}
if (string.trim().equals("÷")) {
return x / y;
}
if (string.trim().equals("/")){
return x / y;
}
return (double) 0;
}
}
2.在計算後綴表達式的類StringToArithmetic
import java.util.Stack;
import java.util.regex.Pattern;
public class StringToArithmetic {
public StringToArithmetic() {
}
// 將中綴表達式字符串計算得到結果
public static double stringToArithmetic(String string) {
return suffixToArithmetic(infixToSuffix(string));
}
// 將中綴表達式轉換為後綴表達式
public static String infixToSuffix(String exp) {
Stack<Character> s = new Stack<Character>();
String suffix = "";
int length = exp.length(); // 輸入的中綴表達式的長度
for (int i = 0; i < length; i++) {
char temp;
char ch = exp.charAt(i);
switch (ch) {
case ‘ ‘:
break;
case ‘(‘:
s.push(ch);
break;
case ‘+‘:
case ‘-‘:
while (s.size() != 0) {
temp = s.pop();
if (temp == ‘(‘) {
s.push(‘(‘);
break;
}
suffix += temp;
}
s.push(ch);
break;
case ‘ב:
case ‘÷‘:
while (s.size() != 0) {
temp = s.pop();
if (temp == ‘+‘ || temp == ‘-‘ || temp == ‘(‘) {
s.push(temp);
break;
} else {
suffix += temp;
}
}
s.push(ch);
break;
case ‘)‘:
//加減乘除以及括號(去除無意義括號較難沒有處理)
while (!s.isEmpty()) {
temp = s.pop();
if (temp == ‘(‘) {
break;
} else {
suffix += temp;
}
}
break;
default:
suffix += ch;
break;
}
}
while (s.size() != 0) {
suffix += s.pop();
}
return suffix;
}
// 將後綴表達式的進行計算得到運算結果
public static double suffixToArithmetic(String exp) {
Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)");
String[] strings = exp.split("");
Stack<Double> stack = new Stack<Double>();
for (int i = 0; i < strings.length; i++) {
if (strings[i].equals("")) {
continue;
}
if (pattern.matcher(strings[i]).matches()) {
stack.push(Double.parseDouble(strings[i]));
}
else {
double y = stack.pop();
double x = stack.pop();
stack.push(calculate(x, y, strings[i]));
}
}
return stack.pop();
}
private static Double calculate(double x, double y, String string) {
if (string.trim().equals("+")) {
return x + y;
}
if (string.trim().equals("-")) {
return x - y;
}
if (string.trim().equals("×")) {
return x * y;
}
if (string.trim().equals("÷")) {
return x / y;
}
return (double) 0;
}
}
遇到的困難及解決辦法
-
問題一:這倆人一直在吵,從頭吵到尾,尤其分數的時候,胡智韜表示不想有分數與整數混合運算,不然太過困難,而陸大嶽則表示整數與分數混合運用,我個人同意胡智韜同學的意見,整數分數混合的題目生成過於復雜,工作量過大,最關鍵的是後綴表達式的分數計算。
-
問題一解決方法:最後是將分數作為除法算了,同歸於盡吧!
-
問題二: 最後運行的時候出現了無限循環的情況,當時忘記了截圖,大概就是:
-
生成4道題目:1+1+2=;1+1+1=;1-1-1=;1+2+3=;1-2+3=;......?!等下怎麽無限循環了!
-
問題二解決方案:後來發現是代碼中case後面忘記加入break。
碼雲項目鏈接
20172312『Java程序設計』課程 結對編程練習_四則運算第二周階段總結