1. 程式人生 > >軟體工程--結對專案

軟體工程--結對專案

在給出github地址之前,我想先介紹一下關於結對專案—四則運算生成這個小專案的使用規則,四個控制檯引數:
(在你想利用GUI頁面進行操作時,選擇以下任一語句輸入)
1.結對專案.exe normal + GUI
2.結對專案.exe normal - GUI
3.結對專案.exe normal * GUI
4.結對專案.exe difficult ** GUI
5.結對專案.exe difficult ^^ GUI
輸入完以上語句之後,你需要輸入:python nnn.py
利用以上語句的組合,你可以得到 簡單模式下,單一運算子的算式,或者困難模式下多運算子、選擇一個乘方運算子的算式。
如果你不想利用介面,你可以輸入下面式子:
1.結對專案.exe normal +
2.結對專案.exe normal -
3.結對專案.exe normal *
4.結對專案.exe difficult **
5.結對專案.exe difficult ^^
以上語句不需要再進行輸入,直接在控制檯進行輸入,判斷對錯等都在控制檯給出提示。
由於考慮到老師的檢查時間,我們讓題目的數量為一個隨機數,隨機數是%1000+1的,由於題目的難度有點大,我們調整了時間為30s。
以上是對在控制檯輸入的解釋


這裡給出有github地址:

結對專案–四則運算生成:

給出psp表格,這裡只寫我個人所用時間:
在這裡插入圖片描述
這次的專案時間和我的預期差距很大,我沒想到我思考在這個問題竟然需要這麼長時間,反倒是編碼,我一個白天就寫完了,所以大部分的時間都花在設計上了。

主體思路

這個四則運算的題目:生成四則運算,括號要隨便加,不能重複,支援真分數,可以判斷對錯,支援乘方,統計答對了多少次。
我得思路,對於單操作符的算式,算式裡面的符號由使用者自己來選擇,我會隨機生成小於等於五個運算數的式子,括號也是隨機進行加上的,是先生成式子,然後在式子裡面加括號,多運算子的式子我的想法是運算子,運算數的個數以及大小都隨機勝場,括號同樣是最後才加,然後我利用逆波蘭表示式及逆行求解,這裡需要注意幾個點,但運算子是不支援除法的,一位內難度太大,同樣的,不能除0,乘方後面的數字不能過大,我都預設的設定為2,這樣方便運算,我把每個結果都存起來,然後你可以通過頁面或者控制檯進行答題。
對於支援真分數的運算,我選擇建立一個分數類,由於只有在多運算子的式子裡才會有分數的出現,所以我把多運算子式子中的數字都用這個類的一個物件來表示,同樣的答案也是如此,我把所有的答案都放到一個vector裡,當想利用介面時候,我就把介面所需要的式子以及答案都輸入到檔案中,這樣就方便了跨語言的協作。

面向物件設計

將uml面向物件技術應用到在這個專案,功能模型要畫用例圖
在這裡插入圖片描述
靜態模型要畫類圖:
在這裡插入圖片描述
plus這個類包括單符號的所有情況
功能模型要畫順序圖,由於這裡互動不是很明顯,所以不再給出順序圖。

程式碼

在這裡給大家看一下重要的程式碼:
這是我分數的大體框架:
在這裡插入圖片描述
這裡重點實現了分數的加減乘除,重點在於約分,這裡我利用輾轉相除法,給大家看一下具體的實現:

int yuefen(int a, int b)
	{
		if (a == 0 || b == 0)
			return 1;
		int c;
		if (a < b)
		{
			a = a + b;
			b = a - b;
			a = a - b;
		}
		c = a % b;
		while (a%b != 0)
		{
			a = b;
			b = c;
			c = a % b;
		}
		return b;
	}

下面是我的normal難度的運算式的類:
在這裡插入圖片描述
我抽象出來的basic類本來以為多重運算子也可以用到,但是發現他倆的出入有點大。
在這個基本的運算式類中,函式有選擇運算模式(±*),列印,將生成的式子,加上括號並運算,在加括號的時候,用到的是類似樹的思想,左右回溯,或者說是二分法,用陣列來存。
給大家重點看一下transforstring這個函式裡面的一些細節:

void transforstring(int max,FILE * file1,vector<int> &a)
	{
		int sum;
		if (n == 2)//只有兩個運算元不需要新增括號
		{
			int j = 0;
			for (int i = 0; i < n; i++)
			{
				if (number[i] >= 10)
				{
					number1[j] = '0' + number[i] / 10;
					j++;
					number1[j] = '0' + number[i] % 10;
					j++;
				}
				else
				{
					number1[j] = '0' + number[i];
					j++;
				}
				if (i == 1)
				{
					number1[j] = '=';
					j++;
				}
				else
				{
					number1[j] = model;
					j++;
				}
				
			}
			sum = j;
		}
		else//超過兩個運算元的情況
		{
			memset(Fkhpos, 0, sizeof(Fkhpos));
			memset(Bkhpos, 0, sizeof(Bkhpos));
			int j = 0;
			int partition = rand() % n;//隨機定義斷點
			if (partition == 0)
				partition++;
			if (khnumhave <= khnum&&whekh==1)
			{
				lefthuisu(1, partition);//左邊回溯
				if (partition != n - 1)
				{
					righthuisu(partition+1, n);//右邊回溯
				}
				
			}
			for (int i = 0; i < n; i++)
			{
				while (Fkhpos[i]!=0)
				{
					number1[j] = '(';
					j++;
					Fkhpos[i]--;
				}
				if (number[i] >= 10)
				{
					number1[j] = '0' + number[i] / 10;
					j++;
					number1[j] = '0' + number[i] % 10;
					j++;
				}
				else
				{
					number1[j] = '0' + number[i];
					j++;
				}
				while (Bkhpos[i] != 0)
				{
					number1[j] = ')';
					j++;
					Bkhpos[i]--;
				}
				if (i != n - 1)
				{
					number1[j] = model;
					j++;
				}
				else
				{
					number1[j] = '=';
					j++;
				}
			}
			sum = j;
		}
		for (int i = 0; i < sum; i++)
			//cout << number1[i];
			fputc(number1[i], file1);
		fputc('\n', file1);//將式子輸入到檔案裡
		int maxm=0;
		for (int i = 0; i < n; i++)
		{
			if (model == '+')
				maxm += number[i];
			if (model == '-')
				maxm -= number[i];
			if (model == '*')
				maxm *= number[i];
			
		}a.push_back(maxm);//將結果存到a裡,方便後續的判對錯
	}

下面是多重運算子式子的類:
在這裡插入圖片描述
函式分別有:選擇乘方的模式,生成表示式,得到答案,進行運算,新增括號時的左右回溯。
運算就是利用兩個棧來實現逆波蘭表示式的計算,計算完畢後,都存入一個vector之中。
主函式就是對控制檯的輸入進行分析這裡詳情可以看個人工程的內容。