接着上次的程序,老師又給二柱子增加了幾個條件,對程序再做進一步的改進,要求滿足如下條件:
1.題目避免重復。
2.可制定。(數量/打印方式)
3.可以控制下列參數:
- 是否有乘除法
- 是否有括號(最多可支持10個數參與計算)
- 數值范圍
- 加減有無負數
- 乘除有無余數
如下是對本題的分析:
針對問題,首先要進行拆分。從最小的功能開始,然后依次實現。首先還是生成一道兩個數的四則運算式,這個不難實現。困難的是如何生成多個數的運算式?其實,多個數的運算只是在兩個數的基礎上進行增加的,所以可以把上一次生成的運算式當作一個數,再與隨機生成的另一個數合成一個運算式,如此循環,直到整個運算式的數字個數滿足我想要達到的數量為止。那么問題又來了,數字是整型,符號為字符型,究竟如何合在一塊進行輸出呢?經過分析發現,字符串有的合成可以直接把幾個字符串相加,於是可以把每一次生成的運算式轉換成字符串的形式來存放,這個過程中要使用到itoa()函數。這樣的話如果要加入“()”也會變得非常簡單,如:equation=‘(’+equation+‘)’+new_num。
而如此一來,對於后面的查重工作,只需把每次新生成的運算式存放在字符串數組中,依次比較之前生成的運算式中是否有相同項,若有,則此次生成無效,再重新生成一個新的運算式,若沒有重復項,則進行下一道運算式的生成工作。直到達到生成運算式的數量為止。
而對其他的要求則可以通過設置用戶選擇來實現,簡單略。
如下是本次問題實現的源代碼:
// 按要求隨機生成四則運算 王世強 2015/3/10 #include<fstream> #include<iostream> #include<stdlib.h> #include<iomanip> #include<time.h> #include<cmath> #include<string> #include<stdio.h> using namespace std; #define random() (rand()%100000) //符號生成 char create_symbol(int n) { int n1,j; char symbol[1]; if(n==0) { n1=2; } else if(n=1) { n1=4; } j=random()%n1; if(j==0) symbol[0]='+'; else if(j==1) symbol[0]='-'; else if(j==2) symbol[0]='*'; else symbol[0]='/'; return symbol[0]; } //把數字轉換成字符串型 string int_string(int number) { int temp=abs(number); char str[200]; itoa(temp,str,10); string str_=str; return str_; } //運算式轉換成一個字符串 string combination(string str1,string str2,char k) { string equation; equation=str1+k+str2; return equation; } //主函數 int main() { srand((int)time(NULL)); //設置時間種子 ,使得程序每次運行的結果都不同 int num1,num2,count,n,change,amount,shuchu,range,j,repeat=0,bracket; string str_num1,str_num2,temp; cout<<"有無乘除法?1有,0沒有:"<<endl; cin>>n; cout<<"是否有括號?1有,0沒有:"<<endl; cin>>bracket; cout<<"題目是否在文件中輸出?1是,0不是:"<<endl; cin>>shuchu; cout<<"請輸入數字范圍:"<<endl; cin>>range; cout<<"請輸入出題數量:"<<endl; cin>>amount; string Equation[amount]; char symbol; ofstream fout; if(shuchu==1) { fout.open("fl.txt"); fout<<amount<<"道四則運算題如下:"<<endl; } else { cout<<amount<<"道四則運算題如下:"<<endl; } for(int i=0;i<amount;i++) { num1=random()%range+1; num2=random()%range+1; count=random()%9+2; symbol=create_symbol(n); str_num1=int_string(num1); str_num2=int_string(num2); Equation[i]=combination(str_num1,str_num2,symbol); if(count>2) { for(count;count>2;count--) { symbol=create_symbol(n); str_num1=Equation[i]; if(bracket==1) { change=random()%2; if(change==0) { str_num1='('+str_num1+')'; } } symbol=create_symbol(n); num2=random()%range+1; str_num2=int_string(num2); change=random()%2; if(change==0) { temp=str_num1; str_num1=str_num2; str_num2=temp; } Equation[i]=combination(str_num1,str_num2,symbol); } } //判斷是否重復 for(j=0;j<i;j++) { if(Equation[j]==Equation[i]) { i=i-1; repeat=1; break; } } if(repeat!=1)//若不重復,則輸出 { if(shuchu==1) { fout<<Equation[i]<<"="<<endl; } else { cout<<Equation[i]<<"="<<endl; } } } if(shuchu==1) { fout.close(); } }
如下是不同條件下運行結果的截圖:


接下來是文件輸出

查看文件內容:

總結:這次的練習,讓我體會到了通過思考解決程序問題的樂趣,回想以前的時候,就是因為怕動手動腦,怕麻煩,總是逃避編程,當醒悟過來時,已經大三了,但是在接下來的時間里,要改掉以前的毛病,珍惜每次練習的機會來提升自己的能力!
項目計划總結:
| 日期&&任務 | 聽課 | 編寫程序 | 閱讀相關書籍 | 網上查找資料 | 日總計 |
| 周一 | 2 | 4 | 2 | 2 | 10 |
| 周二 | 3 | 1 | 4 | ||
| 周三 | |||||
| 周四 | 2 | 2 | 4 | ||
| 周五 | 5 | 1 | 1 | 7 | |
| 周六 | 2 | 2 | |||
| 周日 | 2 | 2 | |||
| 周總計 | 4 | 14 | 7 | 4 | 29 |
時間記錄日志:
| 日期 | 開始時間 | 結束時間 | 中斷時間 | 凈時間 | 活動 | 備注 |
| 3/7 | 14:00 | 15:50 | 10 | 100 | 聽課 | 軟件工程上課 |
| 16:00 | 18:20 | 140 | 編寫程序 | 編寫老師布置的作業 | ||
| 19:00 | 21:00 | 10 | 110 | 閱讀書籍 | 《構建之法》 | |
| 21:00 | 24:00 | 20 | 160 | 網上查找資料,編程 | 作業2,討論問題 | |
| 3/8 | 16:00 | 18:00 | 10 | 110 | 查資料,編寫程序 | 作業2 |
| 21:00 | 21:50 | 50 | 閱讀書籍 | 《構建之法》 | ||
| 3/9 | ||||||
| 3/10 | 14:00 | 15:50 | 10 | 100 | 聽課 | 軟件工程上課 |
| 19:00 | 21:20 | 20 | 100 | 查資料,編寫程序 | 休息,聊天,作業2 | |
| 3/11 | 8:00 | 10:05 | 5 | 120 | 寫博客 | 發表本周博客 |
| 16:10 | 18:30 | 10 | 140 | 修改程序,寫博客 | 測試程序,發表博客 | |
| 19:00 | 19:40 | 40 | 閱讀書籍 | 《構建之法》 | ||
| 19:45 | 21:45 | 10 | 110 | 寫博客,修改程序 | 休息,聊天,發表博客 | |
| 3/12 | 9:00 | 9:30 | 30 | 閱讀書籍 | 計划閱讀《構建之法》 | |
| 3/13 | 19:00 | 19:30 | 30 | 閱讀書籍 | 計划閱讀《夢斷代碼》 |
缺陷記錄日志:
在完成的過程中,改用了新的方法,大部分代碼都有改寫,出現過個別語法錯誤,都是由於馬虎造成的,具體的過程就沒有統計,下周學習過程中會慢慢養成記錄的習慣!
