合作者
031602148 朱文婧 http://www.cnblogs.com/z031602148/)
031602539 翟丹丹 http://www.cnblogs.com/breakbreak/)
)
設計思路
- 首先,我們讨論後決定利用C語言,不會高端操作,設計程式略微繁瑣。
- 編寫時決定用多個函數實作,一個主函數交代大概,剩餘的分函數具體實作。
- 詳細說思路,前面是簡單的介紹大緻思路,很詳細的總函數,還加了個flag,end,判定程式結束,然後是分函數,第一個,沒有括号的走起,中間排除了非負整數,然後是打個基礎,加減乘除每個都講一遍,接着走,一個括号的計算,括号在前,中,後各來一遍,看懂一個就行,其他兩個照搬,嘻嘻,然後是一個括号裡有三個數字的,前中後各來一遍,然後結束,最後那段輸出時是總結的一次性輸出,大緻可以分成四個工作點,主函數,真分數的計算部分,無括号計算,有括号計算,難度依次遞加,我包的後兩個。
-
大略說思路,也就是在主函數裡利用一個随機數,通過switch結構來調用已經編寫好的輸出固定題型的函數,進而做到題型随機。
分函數就是抓住了一個括号這個點,這個括号在前,在中,在後,還有這個括号裡有兩個數字和三個數字時的計算。
-
先介紹下字元的意思。
language:用于進行語言切換,其值通過使用者輸入來決定,1為中文,0為英文。
rig:取right前三個字母,用于統計正确題數;
wro:取wrong前三個字母,用于統計錯誤題數;
flag:用來控制所出題目的難度。初始時指派為0,若得到的随機式子的結果為負或真分數函數外得到的随機式子結果不為整數,則不輸出該式子且将flag指派為1,在主函數的循環結構裡若flag為1,則不對循環變量i做變動,否則i自增1,代表輸出了一道題目。循環的最後會将flag重新指派為0,為下一次的判斷做準備。
test0:用于檢測除數是否為0。初值為0,若出現除數為0的情況,則指派為1,和flag的使用類似,因為是後來添加的,是以沒有将這二者合并。
end:用來判斷程式是否應該停止。初值設為0。分函數裡,把接受答案的變量input的初值設為一個負數,若輸入的内容為字元,則input的值不做改變,之後對input的值進行判斷,若為負數,則說明使用者輸入的為字元(輸出題目的答案不為負),end值變為1,主函數裡對end的值進行判斷,若end為1,停止循環,輸出結果。
temp:設為float型,用來儲存随機出的題目的結果。
test:int型,在計算出temp的值之後會有一條“test=temp”的語句對test的指派,之後則對test和temp的值是否相等進行判斷,若不等,則說明正确答案不為整數,将其放棄不予輸出,反之則輸出。
-
讨論時已經考慮了非負整數這種情況,降低了難度,後來決定再加一個最大公約數和最小公倍數的計算進行約分,例如4/8直接化成1/2.計算真分數的加減時要做到分母相同,于是寫了一個求最小公倍數的函數來實作這一步驟,進而将分子分母擴大相同被倍數進行加減計算。乘除法的計算隻要将分子分母按規則相乘即可。
沒有括号這部分代碼
//輸出含0個括号的式子的函數
void zero()
{
srand((unsigned int)time(NULL)); //設定随機數種子
int input=-8,sign[4],i,test;
float temp[5],arr[5];
char sig[4];
for(i=1;i<=4;i++)
{
arr[i]=rand()%10+0;
}
temp[1]=arr[1];
sig[0]='*';
temp[0]=1;
for(i=1;i<=3;i++)
{
sign[i]=rand()%4+1;
if(sign[i]==1)
{
sig[i]='+';
temp[i+1]=temp[i]+arr[i+1];
}
if(sign[i]==2)
{
sig[i]='-';
temp[i+1]=temp[i]-arr[i+1];
}
if(sign[i]==3)
{
sig[i]='*';
if(sig[i-1]=='-')
temp[i+1]=temp[i-1]-arr[i]*arr[i+1];
else if(sig[i-1]=='+')
temp[i+1]=temp[i-1]+arr[i]*arr[i+1];
else
temp[i+1]=temp[i]*arr[i+1];
}
if(sign[i]==4)
{
if(arr[i+1]==0)
{
test0=1;
break;
}
sig[i]='/';
if(sig[i-1]=='-')
temp[i+1]=temp[i-1]-arr[i]/arr[i+1];
else if(sig[i-1]=='+')
temp[i+1]=temp[i-1]+arr[i]/arr[i+1];
else
temp[i+1]=temp[i]/arr[i+1];
}
有一個括号代碼
//輸出含有一個括号的式子的函數
void kuohao()
{
srand((unsigned int)time(NULL));//設定目前時間為種子
void kuohao1(float big,float arr[5],char sig[4]);
void kuohao2(float big,float arr[5],char sig[4]);
void kuohao3(float big,float arr[5],char sig[4]);
void kuohao4(float arr[5],char sig[4]);
void kuohao5(float arr[5],char sig[4]); //函數聲明部分
int i,choose,symbol;
float big,arr[5];
char sig[4];
for(i=1;i<=4;i++)
{
arr[i]=rand()%10+0;
}
arr[2]=rand()%10+1; //避免下一步的除數中出現0
symbol=rand()%4+1;
switch(symbol)
{
case 1:sig[1]='+';big=arr[1]+arr[2];break;
case 2:sig[1]='-';big=arr[1]-arr[2];break;
case 3:sig[1]='*';big=arr[1]*arr[2];break;
case 4:sig[1]='/';big=arr[1]/arr[2];break;
}
choose=rand()%5+1;
switch(choose)
{
case 1:kuohao1(big,arr,sig);break;
case 2:kuohao2(big,arr,sig);break;
case 3:kuohao3(big,arr,sig);break;
case 4:kuohao4(arr,sig);break;
case 5:kuohao5(arr,sig);break;
}
}
這個地方我們有兩個疑惑點,一個是考慮0時的除法,寫了這一步,arr[2]=rand()%10+1; //避免下一步的除數中出現0。
一個是考慮1加2乘3乘4這種情況,在沒有括号裡算不出來,放在了有一個括号裡。
編碼規範#
1.變量與函數的命名要有理有據,盡量做到見名知意,少使用a,b,c之類的作為變量名,以免造成混亂;
2.注意代碼的排版,盡量做到層次分明,内容直覺,整體美觀,比如循環和條件結構處大括号的使用,按層次縮進之類的;
3.勤加注釋,特别是在關鍵的地方。其中,對于某一函數主要功能的解釋應單獨占一行,标注在函數的開頭,便于與普通注釋區分;
結果測試#

用中英文各試了下。
送出日志#
兩位同學的分工和協作證據截圖#
抱歉這個地方出現了bug,我做的是沒有括号和一個括号的部分,隊友做的是主函數和真分數還有一些補充的零碎部分,在上傳完成體時出現了一些conflicts,在contributors上并沒有出現這段代碼,一開始進行得都很順利,但是在我們準備送出最終結果的時候,就出了問題,至今還是不知道怎麼解決,可能是操作的問題,或者是最後改動太大?
合作過程#
- 開始,一拍即合,選擇C語言。
- 然後開始思索思路,感覺挺合拍的,交流無障礙,互相所說的彼此都能了解,了解錯誤的也能及時指出,然後決定了一個大緻編碼過程,主函數加分函數,四個點,分工明确。
- 我們的分工就是她負責主函數,剩下的分函數我們各拿一部分,各自寫好代碼,然後再精修一下,最後拼在一起。
-
在第一次完成後,着重強調了是0到10的四則運算,在除法裡加了個排除0的計算,這點一開始就都想到了,在精簡過程中考慮到約分化簡這個點,找到一些bug,例如在無括号裡不能實作的移到有一個括号的就能實作了,修改了下基礎程式,最後出來的就是現在比較完整的程式了。
本來是兩個人都在git上送出代碼的,但是結果隻顯示了一個人送出了代碼,原因為何還在探索中,以後會補上的。
合作體會#
- 因為是第一次合作,也是第一次完成這麼大的工作量,程式就比較繁瑣,考慮的也很仔細,互相合作肯定比單打獨鬥高效率,但彼此的空閑時間也會有出入,在另一個人忙時剩餘的會默默完成,這點我很感謝隊友對我的體諒。
- 俗話說,三個臭皮匠敵一個諸葛亮,衆人拾柴火焰高,兩個人的智慧一定比一個人苦思冥想來的精緻,在合作中會時不時令我出現茅塞頓開的感覺。
-
因為是合作,工作量一下子減少好多,隊友是一個細心的人,很多我沒有考慮到的地方她都能夠指出來,給了我很多指點,合作時也争取把沖突降到了最低點,包容了解彼此,期待下次合作。在此@朱文婧,撒花感謝。
最後裡面還是有一個不足,這也是我們努力之後還是沒有完成的,深表遺憾,會繼續加油的!