個人軟件開發過程
上周四(2014年2月20號)軟件工程的課上,老師給推薦了這個博客,感覺真的是一個很不錯的博客,可以記錄自己的編程記錄,同時也能夠發表出去,供行業牛人批評指正。文章正式開始前,先表示一下對王老師的謝意。
這次課上,老師留了這學期的第一個個人作業:寫一個程序,分析一個文本文件(英文文章)中各個詞出現的頻率,並且把頻率最高的10個詞打印出來。這個程序一給出來,很自然的我就想到了用java進行編寫,而且大概的思路已經有了,因為之前做編譯實驗的時候做過類似的文件處理的操作。心里還暗自高興了一下,心想這個程序這么簡單,不出兩個小時就搞定。
到周五的晚上,准備開始做這個題目,20:30,拿着電腦到了自習室,打開電腦之后,聊了會qq,馬上21:00,同學提醒我還得開會,差點忘了,這叫中斷嗎?應該不算吧,因為一直都沒有開始呢。。。開完會回來大概21:20,這個可真得開始了:
這個程序我大概的思路是這樣的:1.首先完成讀文件的操作,然后能夠把文件的內容打印出來。
2.然后,把讀出來的內容,分成單詞。
3.分割成單詞了就開始統計單詞出現的個數,所有的都統計完,把出現頻率最高的10個單詞打印出來即可。
按照這個思路,打開myeclipse,尋找以前的文件處理的代碼(這是不是叫代碼重用啊!!!),很快就完成了讀文件的操作,代碼如下:
BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); System.out.print("請輸入文件的路徑:"); try { fileLoad=in.readLine(); } catch (IOException e) { e.printStackTrace(); } try { FileReader fr = new FileReader(fileLoad); BufferedReader br=new BufferedReader(fr); String cont=br.readLine(); } catch (FileNotFoundException e) { e.printStackTrace(); }
然后開始對讀出來的字符串做處理,分成一個個的單詞,對一個英文句子來說,空格是首先要考慮的:String allWord[]=cont.split(" ");
做到這,大概20分鍾,就收拾東西回宿舍了,剛剛開學,一時還沒有那么用功。
周六,也就是2014年2月22日,上午起來吃了飯,9:00開始完善自己的程序,應該不能說完善,因為本來都沒有完成呢。首先要完成的功能是統計單詞出現的次數。這里我用了兩個集合類,第一個是把分割的所有的單詞存放到一個名為list的集合類中,然后在單詞存放到listNotRepeat集合類中,listNotRepeat中的單詞不能重復。仔細研究了一下英文文章,分割單詞時還要考慮‘;’,‘,’等等之類的:把單詞加入到兩個集合類中的代碼如下:
/* * 讀取文本文件的內容,並將文本文件的內容單詞出現的次數 * 存入到兩個集合類list和listNotRepeat中,list中存放着 * 文本文件中出現的所有的單詞,有重復的;listNotRepeat中也存放着 * 文本文件中出現的單詞,沒有重復的。 */ public void addWordToList(BufferedReader br) { String cont; try { cont=br.readLine(); while(cont!=null) { String allWord[]=cont.split(" |,"); for (int i=0;i<allWord.length;i++) { if(allWord[i].length()>0)//文章中可能存在兩個單詞之間有兩個或更多個空格,去除空格 { if(allWord[i].contains(".")||allWord[i].contains(";")) { String subStringWord[]=allWord[i].split("\\.|;"); for(int j=0;j<subStringWord.length;j++) { if(!listNotRepeat.contains(subStringWord[j])) { listNotRepeat.add(subStringWord[j]); } list.add(subStringWord[j]); } } else { if(!listNotRepeat.contains(allWord[i])) { listNotRepeat.add(allWord[i]); } list.add(allWord[i]); } } } cont=br.readLine(); } } catch (IOException e) { e.printStackTrace(); } }
然后根據兩個集合算出單詞出現的次數,並把每個單詞對應出現的次數以一個javabean的對象的形式存放到另一個集合類wordList中,以便打印出現頻率最高的前十個單詞使用。
for(int i=0;i<listNotRepeat.size();i++)//將每個單詞出現的次數計算出來 { int a=Collections.frequency(list,listNotRepeat.get(i)); wordList.add(new Word((String) listNotRepeat.get(i),a)); }
這里面出現的Word類的定義是這樣的:
package cn.stdu.edu.domain; public class Word { private String wordName; private int time; public String getWordName() { return wordName; } public void setWordName(String wordName) { this.wordName = wordName; } public int getTime() { return time; } public void setTime(int time) { this.time = time; } public Word(String wordName,int time) { this.wordName=wordName; this.time=time; } }
到這,本來想的馬上就做完了,因為只剩下把出現頻率最高的打印出來。就先休息了一下(這應該叫中斷吧 哈~~zz).
休息完了,回來開始動手寫代碼,╮(╯▽╰)╭,不知道怎么寫了,想排序吧,但是不知道怎么排,集合類里面也沒有相關的方法,因為涉及到鍵值對,這里難住了。。。通過查資料什么的,最后確定下來了一種方法,就是前面用到了word對象的集合類wordList。我的思路是,遍歷10次,每一次找到出現次數最大的那個對象,然后記錄這個對象在wordList集合類中的索引值,然后打印出相應的單詞和在文章中出現的次數,再把它從集合類中刪除掉。代碼如下:
/** * 打印出現頻率最高的前10個單詞 */ int max=0; int n=0; //記錄次數出現最多的單詞對象在幾何對象中的索引值 System.out.println("單詞出現頻率最高的10個單詞:"); System.out.println("單詞\t\t\t次數"); for(int j=0;j<10;j++) { for(int i=0;i<wordList.size();i++) { if(max<wordList.get(i).getTime()) { max=wordList.get(i).getTime(); n=i; } } System.out.println(wordList.get(n).getWordName()+"\t\t\t"+max); wordList.remove(n); n=0; max=0; }
到這為止,這個程序似乎是做完了。也能夠輸出正確的結果了,但是作為這個程序的開發者,我肯定知道這個輸入路徑的時候只能輸入什么,但是如果它作為一個軟件交給用戶的時候,用戶肯定有輸入錯誤的時候,那么如果輸入錯誤,會出現什么呢?結果出現了下面的結果:
這些東西給我自己看是重要的參考信息,但是要是作為一個項目的話,讓用看到了這樣的東東,后果恐怕很嚴重啊。所以這個異常必須處理,我的處理思路是如果用戶輸入的路徑不對,應給出相應的提示,三次輸入機會,3次之后還是沒有輸入正確的路徑,程序自動退出。代碼如下:
int cishu=0; while(cishu<=3) { System.out.print("請輸入文件的路徑:"); try { fileLoad=in.readLine(); } catch (IOException e) { e.printStackTrace(); } try { FileReader fr = new FileReader(fileLoad); BufferedReader br=new BufferedReader(fr); readAndPrint.addWordToList(br);//這里是調用的addWordList方法,就是前面提到的list和listNotRepeat集合類的賦值 readAndPrint.printWord(); //這個方法的功能是查找單詞出現的次數,並打印出出現頻率最高的前10個單詞 cishu=4; } catch (FileNotFoundException e) { System.out.println("未找到相應文件,請檢查路徑輸入是否正確!"); if(3==cishu) { System.out.println("\n程序退出,謝謝使用!"); } else { System.out.println("\n還有"+(3-cishu)+"次機會"); } }finally { cishu++; } }
結果顯示如下:
這次這個結果就挺令人滿意了,相信用戶看到這個,也只能怨自己輸入的不正確了。 到這這個程序就算完成了,一直弄到12點,中間夾帶着中斷了一會,洗了洗衣服。
程序中出現的問題: 統計次數; 解決方案:先是想到了一種自己的解決方案,但是太過啰嗦,影響效率,通過搜集資料,查到了相應的方法,解決了該問題
排序; 解決方案:想通過數組排序來解決,這樣也可以。但是想到了直接找出現次數最多的那個單詞實現起來更方便一點,如此就解決了
以上是我整個編寫程序的過程,不足之處請大家指明,並提出自己寶貴的意見,謝謝。