Implementation of WC in JAVA
Implementation of WC in JAVA
github地址
相關要求
基本功能
- -c [文件名] 返回文件的字符數 (實現)
- -w [文件名] 返回文件的詞的數目 (實現)
- -l [文件名] 返回文件的行數 (實現)
擴展功能
- -s 遞歸處理目錄下符合條件的文件。 (實現)
- -a 返回更復雜的數據(代碼行/空行/注釋行)(實現)
- 支持各種文件的通配符(*,?) (實現)
高級功能
- 基本的Windows GUI 程序操作(實現)
- 支持通過圖形界面選取文件(實現)
- 支持通過圖形界面展現文件的信息(實現)
PSP
| Planning | 計劃 | 30 | 35 |
| · Estimate | · 估計這個任務需要多少時間 | 30 | 35 |
| Development | 開發 | 1120 | 850 |
| · Analysis | · 需求分析 (包括學習新技術) | 180 | 120 |
| · Design Spec | · 生成設計文檔 | 120 | 60 |
| · Design Review | · 設計復審 (和同事審核設計文檔) | 60 | 40 |
| · Coding Standard | · 代碼規范 (為目前的開發制定合適的規范) | 100 | 60 |
| · Design | · 具體設計 | 180 | 120 |
| · Coding | · 具體編碼 | 300 | 360 |
| · Code Review | · 代碼復審 | 60 | 30 |
| · Test | · 測試(自我測試,修改代碼,提交修改) | 120 | 60 |
| Reporting | 報告 | 140 | 105 |
| · Test Report | · 測試報告 | 60 | 60 |
| · Size Measurement | · 計算工作量 | 60 | 30 |
| · Postmortem & Process Improvement Plan | · 事后總結, 并提出過程改進計劃 | 20 | 15 |
| 合計 | 1260 | 955 |
設計說明
graph LR A[MainWork] --> B(controller) A[MainWork] --> C(UI) B(controller) --> D(WordCounter) B(controller) --> E(FileFinder) C(UI) --> F(NewJFrame) graph TB A[WordCounter] --> B[CharacterSum] A[WordCounter] --> c[Rows_Number] A[WordCounter] --> d[word_cal] A[WordCounter] --> e[isCodeLine] A[WordCounter] --> f[isEmptyLine] A[WordCounter] --> h[ScanFileinRecursion] A[WordCounter] --> I[getRelatedFiles] e[isCodeLine] --> g[isAnnotationLine] f[isEmptyline] --> g[isAnnotationLine]MainWork: 通過輸入的參數來調用模塊WordCounter中的方法實現基本要求和擴展要求,以及調用實現高級要求中的圖形化界面
controller: 基本功能與擴展功能模塊包
Word Counter:實現-c 統計文件字符數方法,實現-w 統計文件單詞數方法,實現-l 統計文件行數,以及實現 -a中統計文件注釋行,代碼行,空行和-s的遞歸處理目錄下文件的命令參數。
FileFinder:實現支持處理文件名通配符
UI(圖形界面):NewJFrame 是為了實現處理-x參數傳入時所設計的JAVA Swing圖形化界面
解題思路與關鍵代碼
代碼
-c 統計文件字符數
解題思路 -FileReader讀入文件,讀入時計數器同時遞增即可記錄文件字符數目,單文件不存在計數器置為-1,與空文件區別開
public static int CharacterSum(File file) throws IOException {int count_Char = 0;if(!file.exists()){count_Char = -1;return count_Char;}FileReader fr = new FileReader(file);while(fr.read()!=-1){count_Char++;}return count_Char;}-l 統計文件行數
解題思路 通過文件讀入方式以字符緩沖輸入流讀入,緩沖字符,從而實現以行讀取并計數器計算出行數,文件不存在時同上處理
public static int Rows_number(File file) throws IOException {int count_Row = 0;if(!file.exists()){count_Row = -1;}else{FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);String s = null;while((s=br.readLine())!=null){count_Row++;}}return count_Row;}-w 統計文件單詞數
解題思路 學習了正則表達式,readLine每行讀入文件與正則表達式匹配從而計算出單詞數,文件不存在同上處理
public static int word_cal(File file) throws IOException {int count_Word = 0;if(!file.exists()){count_Word = -1;}else{FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);String s = null;while((s=br.readLine())!=null){String reg = "\\d+.\\d+|\\w+";Matcher mat = Pattern.compile(reg).matcher(s);while(mat.find()){count_Word++;}}}return count_Word;}-a 統計文件空行,代碼行,注釋行
解題思路與代碼
- 空行統計:根據需求,空行不得多于一個可顯示字符,readLine讀入文件每行字符串.trim()去掉空格和格式控制符,若字符串長度不大于1則空行計數器加一,文件不存在同上處理
- 代碼行統計:將文件readLine讀入,每行字符串.trim()去掉空格,格式控制符之后通過正則表達式將注釋符號//、/**/等匹配并刪除,并對某些特殊情況進行處理,保留換行符,并append到StringBuffer中,最后將StringBuffer放入一個字符緩沖器當中并統計行數,即可得出代碼行數目。文件不存在同上處理
- 注釋行數目:通過以上對總行數,空行數,代碼行數目的計算,則可以通過調用以上方法可得出注釋行數目=總行數-空行數-代碼行數目
-s 遞歸處理目錄下符合條件的文件。
解題思路 將非根目錄文件夾的文件路徑名通過遞歸方法放入List中
public static List<String> ScanFileInRecursion(File file){if(!file.isDirectory()){System.out.println("非合法目錄文件夾!請重新輸入!");}else{File[] files = file.listFiles();for(int i=0;i<files.length;i++){if(files[i].isDirectory()){ScanFileInRecursion(files[i]);}else{System.out.println(files[i].getAbsolutePath());filepath.add(files[i].getAbsolutePath());}}}return filepath;}支持各種文件的通配符(*,?)
解題思路 使用的是JDK 1.7,Files.walkFileTree,經過學習發現比File類的遍歷效率要高很多,FileFinder類繼承FileVisitor適配器SimpleFileVisitor,在編程設計中,Glob是一種模式,使用通配符來指定文件名,例如*.java,在Glob模式廣泛使用通配符* 和 ?,通過files.walktreefile和NIO庫中的glob模式,則可以遍歷找出相關文件從而支持文件通配符
FileFinder:
public class FileFinder extends SimpleFileVisitor<Path> {private final PathMatcher matcher;private List<Path> matchedPaths = new ArrayList<Path>();private List<Path> matchedAbPaths = new ArrayList<Path>();FileFinder(String pattern){matcher = FileSystems.getDefault().getPathMatcher("glob:"+ pattern);}void match(Path file){Path name = file.getFileName();if(name!=null && matcher.matches(name)){matchedPaths.add(name);matchedAbPaths.add(file.toAbsolutePath());}}@Overridepublic FileVisitResult visitFile(Path file,BasicFileAttributes attrs){match(file);return CONTINUE;}@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs){match(dir);return CONTINUE;}@Overridepublic FileVisitResult visitFileFailed(Path file, IOException exc){System.err.println(exc);return CONTINUE;}public int getTotalMatches(){return matchedPaths.size();}public Collection<Path> getMatchedPaths(){return matchedPaths;}public List<Path> getMatchedAbPaths(){return matchedAbPaths;}}WordCounter的getRelatedFiles方法:
public static List<Path> getRelateFiles(String filepath) throws IOException {FileFinder finder = new FileFinder(filepath);Files.walkFileTree(Paths.get(System.getProperty("user.dir")),finder);Collection<Path> Absolutematched = finder.getMatchedAbPaths();return (List<Path>) Absolutematched; }-x 圖形化界面功能
解題思路 根據Java的Swing設計界面,通過filechooser來選擇文件進行wordcount功能演示。
界面設計部分具體太多則不貼出,下面只貼按鈕監聽事件部分:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) throws IOException, IOException {// TODO add your handling code here:jTextArea1.setText("");JFileChooser jfc=new JFileChooser();jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );jfc.showDialog(new JLabel(), "選擇");File file=jfc.getSelectedFile();if(file.isDirectory()){System.out.println("文件夾:"+file.getAbsolutePath());}else if(file.isFile()){System.out.println("文件:"+file.getAbsolutePath());}System.out.println(jfc.getSelectedFile().getName());BufferedReader br = new BufferedReader(new FileReader(file));String s = null;while((s=br.readLine())!=null){jTextArea1.append(s+"\n");}br.close();int char_count = CharacterSum(file);int word_count = word_cal(file);int line_cunt = Rows_number(file);int empty_line = isEmptyLine(file);int code_line = isCodeLine(file);int annotate_line = isAnnotationLine(file);if(char_count==-1||word_count==-1||line_cunt==-1||empty_line==-1||code_line==-1||annotate_line==-1){chara.setText("字符數:0");jLabel2.setText("單詞數:0");jLabel3.setText("總行數:0");jLabel4.setText("空行數:0");jLabel5.setText("注釋行:0");jLabel6.setText("代碼行:0");}else{chara.setText("字符數: "+char_count);jLabel2.setText("單詞數: "+word_count);jLabel3.setText("總行數: "+line_cunt);jLabel4.setText("空行數: "+empty_line);jLabel5.setText("注釋行: "+annotate_line);jLabel6.setText("代碼行: "+code_line);}}測試
命令行輸入參數測試-c -w -l -a:
- 一個典型源文件:
- 一個空文件:
- 只有一個字符的文件
- 只有一個單詞的文件
- 只有一行的文件
測試-s:
測試 -x:
- 測試典型源文件
- 測試空文件
- 測試只有一個字符的文件
- 測試只有一個單詞的文件 *測試只有以行的文件
測試文本典型源文件:
#include<bits/stdc++.h> using namespace std;typedef long long ll; const int mod = 1e9+7; void exgcd(ll a,ll b,ll &x,ll &y) {/*歐幾里得 */if(b==0){x = 1;y = 0;return ;}ll x1,y1;exgcd(b,a%b,x1,y1);x = y1;y = x1-(a/b)*y1; } int main() {//code here ll n,m;while(cin>>n>>m){ll res = 1;for(ll i=1;i<=n+m-4;i++)res = (res*i)%mod;for(ll i=1;i<=n-2;i++){ll x,y;exgcd(i,mod,x,y);x = (x%mod+mod)%mod;res = (res*x)%mod;}for(ll i=1;i<=m-2;i++){ll x,y;exgcd(i,mod,x,y);x = (x%mod+mod)%mod;res = (res*x)%mod;}res = (res%mod+mod)%mod;cout<<res<<endl;}return 0; }代碼覆蓋率
小結
在設計完成該項目的時候收獲很多,認識到對自己個人項目的設計的不足,包括時間的分配不科學,以及設計過程中對某些細節沒有仔細考慮清楚,就開始著手程序,導致后面做了很多調整,讓我覺得以后自身在學習開發時要多在前期設計下多點功夫。同時深刻了解到自己代碼的不規范所帶的問題。這次課程項目的開發用到了Java開發,過程中也學習到了不少新的東西,對以前學的東西有了進一步的了解,包括對如何通配符支持的研究和對正則表達式的深一步理解運用。希望自己能夠在以后的項目設計和編寫中通過學習和反省從而達到高效。
轉載于:https://www.cnblogs.com/laomiXD/p/9636161.html
總結
以上是生活随笔為你收集整理的Implementation of WC in JAVA的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一文弄懂神经网络中的反向传播法——Bac
- 下一篇: meta viewport相关