軟工第二次作業——熟悉使用工具


GIT地址 我的GITHUB地址
GIT用戶名 NyimaC
學號后五位 61111
博客地址 我的博客地址
作業鏈接 鏈接

Part1.環境配置

因為之前已經用JAVA寫過程序,所以環境是已經配好了的,在此沒有遇到太大的問題。
JAVA版本是JAVA8.0 編譯器使用的是IDEA


Part2.代碼編寫

編碼題目:

阿超家里的孩子上小學一年級了,這個暑假老師給家長們布置了一個作業:家長每天要給孩子出一些合理的,但要有些難度的四則運算題目,並且家長要對孩子的作業打分記錄。

作為程序員的阿超心想,既然每天都需要出題,那何不做一個可以自動生成小學四則運算題目與解決題目的命令行 “軟件”呢。他把老師的話翻譯一下,就形成了這個軟件的需求:

程序接收一個命令行參數 n,然后隨機產生 n 道加減乘除(分別使用符號+-*/來表示)練習題,每個數字在 0 和 100 之間,運算符在 2 個 到 3 個之間。

由於阿超的孩子才上一年級,並不知道分數。所以軟件所出的練習題在運算過程中不得出現非整數,比如不能出現 3÷5+2=2.6 這樣的算式。

練習題生成好后,將生成的 n 道練習題及其對應的正確答案輸出到一個文件 subject.txt 中。

使用語言:JAVA

與題目不同的地方的聲明:

1、運算符存在差異。題目上的是(+-*/) 我的是(+-×÷)

2、我的文件名為“題目.txt”

編碼思路:

思維導圖:

代碼部分(主要部分):

"Talk is cheap. Show me the code."

結構

生成題目的類

public class FormulaMakerTest {
/**
 * 生成題目的類
 */

public LinkedList<String> questionMaker(int total)
{
	//用於存放生成的運算式
	String[] formulas = new String[total];
	LinkedList<String> questionList = new LinkedList<>();
	Numbers numbers = new Numbers();
	OperationImpl operation = new OperationImpl();
	OperationStringImpl operationString = new OperationStringImpl();

	//循環開始的參數(一個用於外循環,一個用於循環)
	int start1;
	int start2;
	//用於保存每次運算的結果
	int result;
	//用於標識運算是否會出現小數
	int judge = 0;
	for(start1=0; start1<total; start1++) {
		//標識結果集的下標
		//生成隨2~3個的運算符
		numbers.operationNumber = (int)(2+Math.random()*(3-2+1));
		//存放每次運算的結果集
		//生成3~4個參與運算的數字
		numbers.numbers = new Integer[numbers.operationNumber+1];
		for(start2=0; start2<=numbers.operationNumber; start2++) {
			numbers.numbers[start2] = (int)(0+Math.random()*(100-0+1));
		}
		//生成運算符
		numbers.operations = new Integer[numbers.operationNumber];
		for(start2=0; start2<numbers.operationNumber; start2++) {
			numbers.operations[start2] = (int)(1+Math.random()*(4-1+1));
		}
		//運算此表達式的運算結果(重點)
		//1、判斷此算式是否滿足條件(主要看除法是否滿足)
		for(start2=0; start2<numbers.operationNumber; start2++){
			if(numbers.operations[start2] == 4) {
				if(!operation.judgeDivision(numbers.numbers[start2], numbers.numbers[start2+1])) {
					//不滿足 重新生成算式
					judge++;
				}else {
					continue;
				}
			}
		}
		//若滿足除法后無小數,則此算式成立
		//算式中沒有小數,可以生成表達式並打印
		if(judge == 0) {
			//算式中沒有小數,可以生成表達式並打印
			formulas[start1] = operationString.operationSplicing(numbers.operationNumber, numbers.numbers, numbers.operations);
			System.out.println(formulas[start1]);
		}else {
			judge = 0;
			start1--;
			continue;
		}

		//調用計算函數計算結果
		CalculateMaker maker = new CalculateMaker();
		java.util.Queue<String> queue = new LinkedList<>();
		queue = maker.calculateResult(numbers.numbers, numbers.operations);
		result = maker.calculate(queue);
		formulas[start1] += String.valueOf(result);
		questionList.add(formulas[start1]);
	}
	return questionList;
	}
}

棧進行四則運算的類

public class CalculateMaker {
/**
 * 用於獲得后綴表達式
 * @return
 */
public Queue<String> calculateResult(Integer[] num, Integer[] operations) {
	//用於存放之前的算式
	Queue<String> queue1 = new LinkedList<>();
	//用於存放后綴表達式
	Queue<String> queue2 = new LinkedList<>();
	int i;
	//把運算式放入隊列
	for(i=0; i<num.length; i++) {
		queue1.offer(String.valueOf(num[i]));
		if(i<operations.length){
			switch (operations[i]){
				case 1:
					queue1.add("+");
					break;
				case 2:
					queue1.add("-");
					break;
				case 3:
					queue1.add("×");
					break;
				case 4:
					queue1.add("÷");
					break;
				default:
					break;
			}
		}
	}

	//用於存放運算符
	Stack<String> stack = new Stack<>();
	//用於標注隊列中運算符的位置
	i = 2;
	while(!queue1.isEmpty()) {
		//此位置是運算符
		if(i%2==1) {
			i++;
			int num1, num2;
			//把運算符放進去
			if(stack.empty()) {
				stack.push(queue1.poll());
			}else {
				//取隊首元素的值(用Unicode碼來判斷,加減號的值小於100,乘除號的值大於100)
				num1 = Translate.translateToInt(queue1.poll());
				if(num1<100) {
					while (!stack.isEmpty()) {
						queue2.offer(stack.pop());
					}
					stack.push(Translate.translateToString(num1));
				}else {
					num2 = Translate.translateToInt(stack.peek());
					if(num2<100) {
						stack.push(Translate.translateToString(num1));
					}else {
						queue2.offer(stack.pop());
						if(stack.isEmpty()) {
							stack.push(Translate.translateToString(num1));
						}else {
							while(!stack.isEmpty()) {
								if(stack.isEmpty()) {
									stack.push(Translate.translateToString(num1));
									break;
								}
								num2 = Translate.translateToInt(stack.peek());
								if(num2<100) {
									stack.push(Translate.translateToString(num1));
									break;
								}else {
									queue2.offer(stack.pop());
								}
							}
						}
					}
				}
			}
		}else {
			i++;
			queue2.offer(queue1.poll());
			if(queue1.isEmpty()){
				while(!stack.isEmpty()) {
					queue2.offer(stack.pop());
				}
			}
		}
	}
	//打印后綴表達式並返回
	return queue2;
}

/**
 * 根據后綴表達式計算結果
 * @param queue2
 * @return
 */
public int calculate(Queue queue2) {
	/**
	 * 用於進行后綴計算
	 */
	OperationImpl operation = new OperationImpl();
	//保存計算結果
	int x = 0;
	int y = 0;
	int result = 0;
	Stack<String> stack = new Stack<>();
	stack.push((String)queue2.poll());
	while(!queue2.isEmpty()) {

		String str = (String) queue2.poll();
        //遇到運算符,出棧運算,結果入棧
		if(!operation.judgeOperation(str)) {
			stack.push(str);
		}else {
				 y = Integer.valueOf(stack.pop());
				 x = Integer.valueOf(stack.pop());
				 result = operation.calculateNumber(x, y, str);
				 stack.push(String.valueOf(result));
				 //如果最終只有一個元素,則為計算的結果
				 if(stack.size() == 1 && queue2.isEmpty()) {
				 	return Integer.valueOf(stack.pop());
				}
		}
	}
	return y;
}

}

主函數

public static void main(String[] args) {
	//輸入想要的題目數
	System.out.println("請輸入想要創建題目的數目:");
	//生成題目的數目
	Scanner scanner = new Scanner(System.in);
	int total = scanner.nextInt();
	//生成題目生成器
	FormulaMakerTest maker = new FormulaMakerTest();
	//題目集
	LinkedList<String> questionList = 	maker.questionMaker(total);
	System.out.println(questionList);
	//將題目存入文件中
	FileWriting writing = new FileWriting();
	writing.WriteStringToFile(questionList);
}

控制台打印的題目

文件中保存的題目


Part3.使用github克隆項目以及提交代碼

下載與安裝

官網上下確實有點慢,找同學要的其他資源下的。

配置個人信息

指令:

git config --global user.name "用戶名"

git config --global user.email 郵箱

克隆項目

進入這里
點這里,復制這里的url

在Git的文件夾下創建一個新的文件夾,在新的文件夾內右鍵選擇Git Bash Here, 然后再在界面上輸入git clone + 剛才復制網址,即 https://github.com/Cherish599/AchaoCalculator

提交代碼

成功后便會多出一個文件夾,在里面創建一個和自己github用戶名一致的文件,將程序源碼放進去。

然后轉到AchaoCalculator文件目錄下(cd 文件的路徑)
然后輸入git add . , 再輸入git commit -m "分支名稱",最后輸入 輸入 git push,在這里會彈出框讓你輸入GitHub的用戶名和密碼即可

最后在GitHub上就能看到你提交的文件啦

遇到的問題

1、第一次接觸GitHub,大多是看着教程操作的,以后需要多多熟悉

2、很多指令不熟悉,有的教程上的地方我用起來會出現錯誤,在其他地方找了解決的辦法


Part4.單元測試

因為在編程過程中有很多需要單元測試的地方,也有很多bug需要及時修改,所以沒有細致的記錄,在此簡單的描述一下

JAVA的單元測試可以基於Junit,並需要在測試的方法前加上@Test注解且測試方法不能存在參數

同時也可以基於main()方法來測試,並在需要的地方輸出語句

主要遇到的問題

1、表達式的生成(字符串的拼接)出現錯誤。因為運算符是運用1~4的隨機數來保存的,所以生成算式時需要轉化為加減乘除對應的符號,思考后得以解決。

2、后綴表達式生成出現錯誤。因為對中綴表達式轉化為后綴表達式的理解還存在一些偏差。在仔細閱讀概念,並不斷得打印后綴表達式后,找出了代碼中出現的問題,最后得以解決

3、得到后綴表達式后計算結果出現錯誤。后綴表達式存在一個隊列中,隊列中元素的出隊,以及數字元素的壓棧、出棧操作出現問題。在條件語句中多次進行打印操作后,找出了錯誤出現的位置,找到原因,最終得以解決。

4、如果除法存在小數如何解決。我才用的方法是將此次循環作廢,即將循環因子的值減一,並不進行拼接操作。


Part5.回歸測試

單元測試時會存在許多問題,解決了這些問題,也就是進行了回歸測試,同樣在編程過程中有很多的回歸測試,所以沒有過多去記錄

這是進行單元測試后,再進行回歸測試才得出的判斷運算結果是否為小數的方法。

得出的判斷方法:看兩個整數相除后的結果與其強轉成浮點型后的結果是否一樣,一樣則是整數,反之則是小數


Part6.總結

說實話感覺這次作業還是很有難度的。主要是編寫代碼部分就需要大量的時間與精力。數據結構在學棧的部分學習過四則運算優先級判斷,但是當時沒有用代碼實現,所以還花時間去學習了一下。

學習Git的使用過程中,好在有很多文章可以參考,雖然陌生但是操作起來還是比較容易。

環境因為是以前就配好的,同時單元測試和回歸測試其實在代碼的編寫中以及有所使用了,這方面進行的還是比較順利。

總之這次作業還是讓我收獲頗豐,無論是對編程語言JAVA,還是數據結構中棧和隊列,以及Git的使用都得到了很好的練習


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM