實現一個命令行程序,要求:git
從題目要求可知,咱們須要實現如下幾個功能:express
現階段已實現要求二、3,要求4雖已初步實現但仍存在一些問題,咱們將會在下一階段中實現全部項目要求的功能,並可拓展如下功能:編程
根據需求,考慮程序須要定義方法來實現中綴表達式轉後綴表達式、後綴式計算的功能,將結果轉換爲分數以及須要定義調用以上三種種方法並進行輸入輸出的主類,因而我將前兩種方法放入MyDC的類中,真數的支持放入Rational類中,主類設置爲MyDCTester。數組
運用老師在博客中提供的法則:post
public String trans(String before){ int i,j=0; char step[] = before.toCharArray();//將中綴式字符串轉化爲字符數組 char after[] = new char[step.length];//用於接收轉化後的後綴式表達式 for(i=0;i<step.length;i++) { if (step[i] >= '0' && step[i] <= '9') {//遇到數字 after[j] = step[i]; j++; if(i==(step.length)-1){//讀到了輸入的末尾 while(stacktwo.empty()==false) { after[j]=stacktwo.pop(); j++; } } } else if(stacktwo.empty()||step[i]=='('||stacktwo.peek()=='('||stacktwo.peek()==')') {//遇到非數字且棧爲空或者該符號爲左括號或者棧頂元素爲括號 stacktwo.push(new Character(step[i])); if(i==(step.length)-1){ while(stacktwo.empty()==false) { after[j]=stacktwo.pop(); j++; } } } else if(step[i]==')') {//遇到一個右括號 while (stacktwo.peek() != '(') { after[j] = stacktwo.pop(); j++; } stacktwo.pop(); if(i==(step.length)-1){ while(stacktwo.empty()==false) { after[j]=stacktwo.pop(); j++; } } } else {//遇到運算符號且棧非空 switch (step[i]) { case ADD: case SUBTRACT: { while(stacktwo.peek()=='*'||stacktwo.peek()=='/'||stacktwo.peek()=='+'||stacktwo.peek()=='-'){ after[j]=stacktwo.pop(); j++; if(stacktwo.empty()){ break; } } stacktwo.push(step[i]); break; } case MULTIPLY: case DIVIDE: { while(stacktwo.peek()=='*'||stacktwo.peek()=='/'){ after[j]=stacktwo.pop(); j++; if(stacktwo.empty()){ break; } } stacktwo.push(step[i]); break; } } if(i==(step.length)-1){ while(stacktwo.empty()!=false) { after[j]=stacktwo.pop(); j++; } } } } String str = new String(after); return str;//將字符數組轉化爲字符串後返回 }
老師給的連接中已經明確給出了計算的方法,方法以下:學習
public int evaluate(String expr) {//計算後綴式的值 int op1, op2, result = 0,i; char token[]=expr.toCharArray();//將後綴式字符串轉化爲字符數組 for(i=0;i<token.length;i++){ if (token[i]=='+' || token[i]=='-' || token[i]=='*' || token[i]=='/') {//對每一個字符進行分析,若是是運算符就取出棧頂開始的兩個數 op2 = stack.pop(); op1 = stack.pop(); result = evalSingleOp(token[i], op1, op2);//將棧中取出的兩個數進行運算 stack.push(new Integer(result));//將結果壓棧 } else//爲數字時直接進棧 stack.push(new Integer((int)(token[i]-'0'))); } return result;//返回計算結果 } private int evalSingleOp(char operation, int op1, int op2) {//對棧中取出的兩個數進行四則運算,operation爲後綴式中的運算符號 int result = 0; switch (operation) { case ADD: result = op1 + op2; break; case SUBTRACT: result = op1 - op2; break; case MULTIPLY: result = op1 * op2; break; case DIVIDE: result = op1 / op2; } return result;//返回運算結果 }
咱們經過學習教材上第100頁的例子22封裝了有理數類Rational,實現了對真分數的支持。
代碼以下:測試
public class Rational { int numerator = 1;//分子 int denominator = 1;//分母 void setNumerator(int a) {//設置分子 int c = f(Math.abs(a), denominator);//計算最大公約數 numerator = a / c; denominator = denominator / c; if (numerator < 0 && denominator < 0) { numerator = -numerator; denominator = -denominator; } } void setDenominator(int b) {//設置分母 int c = f(numerator, Math.abs(b));//計算最大公約數 numerator = numerator / c; denominator = b / c; if (numerator < 0 && denominator < 0) { numerator = -numerator; denominator = -denominator; } else if (numerator > 0 && denominator < 0) { numerator = -numerator; denominator = -denominator; } } int getNumerator() { return numerator; } int getDenominator() { return denominator; } int f(int a, int b) {//求a,b的最大公約數 if (a == 0) { return 1;//c爲分母不能爲0 } if (a < b) {//令a>b int c = a; a = b; b = c; } int r = a % b; while (r != 0) { a = b; b = r; r = a % b; } return b; } Rational add(Rational r) {//加法運算 int a = r.getNumerator();//返回有理數r的分子 int b = r.getDenominator();//返回有理數r的分母 int newNumerator = numerator * b + denominator * a;//計算出新分子 int newDenominator = denominator * b;//計算出新分母 Rational result = new Rational(); result.setNumerator(newNumerator); result.setDenominator(newDenominator); return result; } Rational sub(Rational r) {//減法運算 int a = r.getNumerator(); int b = r.getDenominator(); int newNumerator = numerator * b - denominator * a; int newDenominator = denominator * b; Rational result = new Rational(); result.setNumerator(newNumerator); result.setDenominator(newDenominator); return result; } Rational muti(Rational r) {//乘法運算 int a = r.getNumerator(); int b = r.getDenominator(); int newNumerator = numerator * a; int newDenominator = denominator * b; Rational result = new Rational(); result.setNumerator(newNumerator); result.setDenominator(newDenominator); return result; } Rational div(Rational r) {//除法運算 int a = r.getNumerator(); int b = r.getDenominator(); Rational result = new Rational(); if (a == 0) { System.out.println("分母不能爲0"); result.setNumerator(0); System.exit(0); } else { int newNumerator = numerator * b; int newDenominator = denominator * a; result.setNumerator(newNumerator); result.setDenominator(newDenominator); } return result; } }
現階段爲減小程序調試的難度,咱們使用了老師在博客中提供的代碼,但老師提供的代碼沒法實現隨機生成題目、支持真分數以及統計正確率的功能,因而咱們作出了修改,使得程序能夠支持分數輸出,在接下來的編程中咱們會根據需求對這部分代碼進行從新編寫。編碼
public class MyDCTester { public static void main(String[] args) { String expression, again; Rational result=new Rational(); try { Scanner in = new Scanner(System.in); do { MyDC evaluator = new MyDC(); System.out.println("Enter a valid postfix expression: "); expression = in.nextLine();//輸入運算表達式 result = evaluator.evaluate(evaluator.trans(expression));//調用trans方法以及evaluate方法進行轉化以及輸出計算結果 System.out.println(); int a=result.getNumerator(); int b=result.getDenominator(); if (b==1){//分數轉換 System.out.println("result="+a); } else{ System.out.println("result="+a+"/"+b); } System.out.print("Evaluate another expression [Y/N]? ");//詢問用戶是否再次計算 again = in.nextLine(); System.out.println(); } while (again.equalsIgnoreCase("y")); } catch (Exception IOException) { System.out.println("Input exception reported"); }
我已在設計思路部分給出了設計思路並對關鍵代碼進行了註釋。lua
碼雲連接命令行
到目前爲止的困難主要在於實現中綴表達式轉化爲後綴表達式以及分數的轉化,我將一些細節的問題寫在了下面。
-Xlint:deprecation
命令進行編譯,找到問題並修改。個人結對搭檔是江野,在合做的過程當中我是牽頭人,他也積極響應個人號召,在編程過程當中咱們互相學習,在遇到困難時一塊兒討論解決辦法。但願能在之後的任務中繼續合做,也但願搭檔能更加積極地參與到項目中。
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | ||
· Estimate | · 估計這個任務須要多少時間 | 15 | 30 |
Development | 開發 | ||
· Analysis | · 需求分析 (包括學習新技術) | 25 | 35 |
· Design Spec | · 生成設計文檔 | 30 | 30 |
· Design Review | · 設計複審 (和同事審覈設計文檔) | 20 | 30 |
· Coding Standard | · 代碼規範 (爲目前的開發制定合適的規範) | 35 | 45 |
· Design | · 具體設計 | 60 | 80 |
· Coding | · 具體編碼 | 150 | 200 |
· Code Review | · 代碼複審 | 30 | 35 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 20 | 35 |
Reporting | 報告 | 60 | 80 |
· Size Measurement | · 計算工做量 | 10 | 20 |
· Postmortem & Process Improvement Plan | · 過後總結, 並提出過程改進計劃 | 20 | 20 |
合計 | 475 | 640 |