word count 項目總結

1、github地址html

https://github.com/hyt1022/wordcountjava

 

2、PSP表格git

PSP2.1github

PSP階段編程

預估耗時數組

(分鐘)eclipse

實際耗時ide

(分鐘)函數

Planning學習

計劃

30

30

· Estimate

· 估計這個任務須要多少時間

30

30

Development

開發

840

1200

· Analysis

· 需求分析 (包括學習新技術)

60

60

· Design Spec

· 生成設計文檔

60

60

· Design Review

· 設計複審 (和同事審覈設計文檔)

30

30

· Coding Standard

· 代碼規範 (爲目前的開發制定合適的規範)

30

30

· Design

· 具體設計

120

120

· Coding

· 具體編碼

360

600

· Code Review

· 代碼複審

60

60

· Test

· 測試(自我測試,修改代碼,提交修改)

120

240

Reporting

報告

160

240

· Test Report

· 測試報告

100

150

· Size Measurement

· 計算工做量

30

30

· Postmortem & Process Improvement Plan

· 過後總結, 並提出過程改進計劃

30

60

 

合計

1030

1470

 

3、解題思路介紹

 拿到題目後。首先對程序的準備進行了思考。

此次用Java進行編程,選用的編譯器是Myeclipse10,配置的jdk版本是   。由於有一段時間沒有寫java,稍微有些生疏。所以查閱了大二時面向對象程序設計【1】。這本書對於java的基本語法和經常使用類進行了總結和用法指導,深刻淺出。

後面考慮到要生成exe文件,所以在網上查閱瞭如何將java項目打包生成exe文件【2】。

考慮到要將本地項目上傳到github,在網上查閱了用命令行上傳github的方法。【3】

再對程序的實現進行分析。

看到程序很容易就想到去年編譯技術課程。此次的程序也能夠沿用編譯技術的部分的思想。

對於基礎功能。最直接的想法是,經過將須要分析的* .c文件讀入。用一個字符數組進行存儲。對數組從到頭尾掃一遍,在掃的過程當中,分析統計文件的字符,單詞數,行數等。

對於拓展功能。在基礎功能的基礎上,在掃的過程當中考慮更多的因素。對於停用詞表,現將詞表讀入文件,分紅每個停用詞,存入一個動態的字符數組。在掃待測數組時,將讀到的每一個單詞與停用詞表進行比較,統計停用詞的個數。統計代碼行,空行,數據行的基本思路也和基礎功能的一致。可是須要考慮更多的狀態,以分析判斷此行到底屬於哪種類型。

對於基本輸入輸出。輸入方式經過main函數自帶的參數,分析args[],來判斷輸入的指令。輸出則經過輸入的文件名,將輸出結果寫入txt文件。

 

4、代碼說明

public void analyse(String fileName,String stoplistFile,boolean f5) { Readfile(fileName); if(f5) { ReadStoplist(stoplistFile); } file = fileName; String tempword; String tep = new String(tempchars); int flag = 0;//判斷上一個字符的標誌,用來推斷單詞數是否增長;進入單詞分隔符則爲0,進入可顯示字符則爲1
    while(tempchars[p] != '\0') { if(tempchars[p] == '\n') { flag = 0; l++; p++; } else if(tempchars[p] == '\r') { flag = 0; p++; } else if(tempchars[p] == '\t') { flag = 0; p++; } else if(tempchars[p] == ' ') { flag = 0; p++; } else if(tempchars[p] == ',') { flag = 0; p++; } else//若是是可顯示的字符
 { if(flag == 0)//若是上一個是單詞分隔符則單詞數加一
 { w++; if(f5)//若是有停用詞表則進行分析
 { int a=p; while(tempchars[p] != '\n'&&tempchars[p] != '\r'&&tempchars[p] != '\t'&& tempchars[p] != ' '&& tempchars[p] != ','&&tempchars[p]!='\0') { p++; }//將這個單詞的開始位置和結束位置作標記
                    tempword = tep.substring(a, p);//將這個單詞截取下來
                    for(int i=0;i<stopword.size();i++)//將單詞與停用詞表進行對比
 { if(tempword.equals(stopword.get(i))) { s++; } } p=p-1;//當前p指向單詞間的分隔符,退回到此字符的前兩個
 } } flag = 1; p++; } } }
View Code

此段代碼的主要邏輯是一個while循環,循環分析每個字符,以及當前對應的的狀態。

讀到每個字符則字符數加一。

讀到每個換行符則行數加一,最後的行數還要加上第一行。

讀到每個可顯示字符,則判斷前一個字符是否是單詞分隔符,若是是則單詞數加一;若是不是則前一個也是可顯示字符,則爲同一個單詞,單詞數不變。若是有停用詞表,則將單詞截取下來和詞表中的單詞進行對比。

public void analyseAddtion() { int i=0; int flag = 1; //此行是否分配
    int cflag = 0; //此行是否處於註釋裏
    int dflag = 0; // 此行是不是‘*/’的註釋行
    int count =0; //每行有效字符計數
    while(tempchars[i] != '\0') { if(tempchars[i] == ' '||tempchars[i] == '\t'||tempchars[i] == '\r')//若是是空格一類的直接跳過
 { i++; } else if(tempchars[i] == '/') { count++; if(tempchars[i+1] == '/') { if(flag == 1 && count<3 && cflag == 0)//此種狀況可直接判斷爲註釋行
 { comment++; flag = 0; } } else if(tempchars[i+1] == '*') { cflag = 1; i++;//跳過一個字符,防止下一個是‘/’的狀況
 } i++; } else if(tempchars[i] == '*') { count++; if(tempchars[i+1] == '/') { if(cflag ==1) { cflag = 0; i++;//跳過一個字符,防止下一個是‘*’的狀況
                    count = 0; dflag = 1; } } i++; } else if(tempchars[i] == '\n')//到每行末尾,若此行沒有分配則根據當前狀態進行分配
 { if(flag == 1 && cflag == 0 && dflag == 0 && count<2) { empty++; flag = 0; } if(flag == 1 && cflag == 0 && dflag == 0 && count>1) { code++; flag = 0; } if(flag == 1 && cflag == 1) { comment++; flag = 0; } if(flag == 1 && cflag == 0 && dflag == 1) { comment++; flag = 0; dflag = 0; } count = 0; flag = 1; i++; } else//若是是其餘字符
 { count++; if(count > 1 && flag == 1 && cflag == 0)//此種狀況可直接判斷爲代碼行
 { code++; flag = 0; } i++; } } //若最後一行沒有分配,會經過當前狀態進行分配
    if(flag == 1 && dflag == 1) { comment++; } if(flag == 1 && cflag == 1) { comment++; } if(flag == 1 && cflag == 0 && dflag == 0 && count<2) { empty++; } if(flag == 1 && cflag == 0 && dflag == 0 && count>1) { code++; } }
View Code

此段代碼的主要邏輯也是while循環,循環分析每個字符,以及當前對應的的狀態。

若是讀到空格,製表符和回車符,則直接跳過,這個對判斷行沒有影響。

若是讀到’/’,則判斷下一個是否是’/’,若是是且此行沒有肯定是什麼行,並且此行當前的可顯示字符數不超過兩個而且不在註釋範圍內 ,則可判斷是註釋行。若是下一個是’*’,則此行進入註釋範圍內(須要’*/’才能消除此註釋範圍)。

若是讀到’*’,則判斷下一個是否是’/’,若是是,判斷是否在註釋範圍。若是在,退出註釋範圍,將當前可顯示字符數清零,不在則當作兩個可顯示字符便可。

若是讀到‘\n’,到了每行末尾,如此行還沒肯定是什麼行,則根據當前的狀態判斷,便是否在註釋範圍,是不是’*/’的註釋行,是不是空行等。

最後在退出時,也會判斷最後一的狀態,肯定是什麼行。

for(int i=0; i<args.length;i++)//循環判斷每個字符串
 { if(args[i].equals("-c")) { func[0] = true; if((i+1) == args.length)//若是此字符串爲最後一個,則不符合格式,下同
 { error = true; break; } if(args[i+1].charAt(0) != '-')//若是下一個不是'-'開頭的指令,則默認爲文件名,進行讀取,下同
 { i++; filename = args[i]; } } else if(args[i].equals("-w")) { func[1] = true; if((i+1) == args.length) { error = true; break; } if(args[i+1].charAt(0) != '-') { i++; filename = args[i]; } } else if(args[i].equals("-l")) { func[2] = true; if((i+1) == args.length) { error = true; break; } if(args[i+1].charAt(0) != '-') { i++; filename = args[i]; } } else if(args[i].equals("-o")) { func[3] = true; if((i+1) == args.length) { error = true; break; } i++; outputfile = args[i];//'-o'指令後必須接輸出文件名,進行讀取
 } else if(args[i].equals("-e")) { func[4] = true; if((i+1) == args.length) { error = true; break; } i++; stoplistfile = args[i];//'-e'指令後必須接停用詞表文件名,進行讀取
 } else if(args[i].equals("-a")) { func[5] = true; if((i+1) == args.length) { error = true; break; } if(args[i+1].charAt(0) != '-') { i++; filename = args[i]; } } else if(args[i].equals("-s")) { func[6] = true; if((i+1) == args.length) { error = true; break; } if(args[i+1].charAt(0) != '-') { i++; filename = args[i]; } } else { error = true; break; } }
View Code

循環判斷,主函數自帶的參數,是一個字符串數組。由此分析指令。’-c’, ’-w’, ’-l’, ’-a’指令後面若接文件名則是待分析的文件名,進行讀取。‘-o’後接的文件名必然是輸出文件名,’-e’後接的文件名必然是停用詞表。分析後則可獲得程序須要完成哪些功能,並接受到指令中相應的文件名。

 

5、測試設計過程

經過11個測試用例和13個執行語句來對程序進行測試。每一個測試用例均對於不一樣的功能有所側重,覆蓋了系統能實現的絕大部分功能。根據白盒測試的思想,測試用例能也能覆蓋絕大部分的條件判斷語句。用例中出現換行和文件結尾時容易致使程序高風險,用例的字符數太高引發數組越界也會形成高風險。此測試方案基本能知足對此程序功能測試要求。如下會對每一個測試用例進行闡釋和具體說明。

測試1:

用例:file1.c

用例說明:用於測試字符統計的基本功能,此用例包含了空格和製表符,測試可否正確統計空格即製表符。

執行語句:-c file1.c -o output1.txt

預計輸出:file1.c,字符數:15

 

測試2:

用例:file2.c

用例說明::用於測試字符統計的基本功能,此用例包含空行,測試可否統計換行字符。

執行語句:-c file2.c -o output2.txt

預計輸出:file2.c,字符數:22

 

測試3:

用例:file3.c

用例說明:用於測試單詞統計的基本功能,此用例包含換行,空格,逗號隔開,測試可否正確統計單詞數。

執行語句:-w file3.c -o output3.txt

預計輸出:file3.c,單詞數:16

 

測試4:

用例:file4.c

用例說明:用於測試停用詞表功能,此用例測試基本功能,測試可否將例子中須要屏蔽的單詞屏蔽。

執行語句:-w file4.c -e stoplist.txt -o output4.txt

預計輸出:

file4.c,單詞數:13

file4.c,停用後單詞數:10

 

測試5:

用例:file5.c

用例說明:用於測試停用詞表功能,此用例包含單詞中含有停用詞表的單詞但不等於此單詞,測試是否會誤判斷屏蔽。

執行語句:-w file5.c -e stoplist2.txt -o output5.txt

預計輸出:

file5.c,單詞數:20

file5.c,停用後單詞數:20

 

測試6:

用例:file6.c

用例說明:用於測試行統計功能,此用例測試基礎功能,包含空行,只有一個字符的行等。

執行語句:-l file6.c -o output6.txt

預計輸出:file6.c,行數:9

 

測試7:

用例:file7.c

用例說明:用於測試代碼行和註釋行,此用例包含容易混淆的代碼行和註釋行的狀況,測試可否正確統計行數。

執行語句:-a file7.c -o output7.txt

預計輸出:file7.c,代碼行/空行/註釋行: 6/0/3

 

測試8:

用例:file8.c

用例說明:用於測試代碼行和空行,此用例包含不少容易混淆的空行和註釋行的狀況,測試是否能正確統計行數。

執行語句:-a file8.c -o output8.txt

預計輸出:file8.c,代碼行/空行/註釋行: 0/1/4

測試9:

用例:file9.c

用例說明:用於測試空行和代碼行,此用例包含容易混淆的代碼行和空行的狀況,測試時候能正確統計行數。

執行語句:-a file9.c -o output9.txt

預計輸出:file9.c,代碼行/空行/註釋行: 2/4/0

 

測試10:

用例:file10.c

用例說明:用於測試代碼行,空行,註釋行。此用例爲綜合用例,包含各類可能混淆的狀況,測試可否正確統計行數。

執行語句:-a file10.c -o output10.txt

預計輸出:file10.c,代碼行/空行/註釋行: 11/1/16

 

測試11:

用例:file1.c

用例說明:用來測試在不提供製定輸出文件下,可否將結果輸出在默認文件result.txt中。

執行語句:-l file1.c

預計輸出:file1.c,字符數:15

 

測試12:

用例:當前文件夾中全部「.c」文件

用例說明:用於測試可否遞歸處理當前文件夾中全部符合條件的文件。

執行語句:-w -s .*.c -o output12.txt

預計輸出:(較多不予以顯示)

 

測試13:

用例:file11.c

用例說明:用於測試全功能,包含全部的功能指令,給出的用例中也包含了各類可能處理的狀況,測試可否正常運行並給出正確的結果。

執行語句:-c -w -l -a -s *.c -e stoplist.txt -o output13.txt

預計輸出:(較多不予以顯示)

 

6、參考文獻

【1】面向對象程序設計教程,任宏萍編著。

【2】https://www.cnblogs.com/yxwkf/p/4609765.html

【3】https://jingyan.baidu.com/article/0202781145eaab1bcc9ce5f0.html

相關文章
相關標籤/搜索