WordCount--实现字符,单词,代码统计
Github:
https://github.com/whoNamedCody/WordCount
PSP表格
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
10 | 15 |
· Estimate |
· 估计这个任务需要多少时间 |
20 | 20 |
Development |
开发 |
180 | 250 |
· Analysis |
· 需求分析 (包括学习新技术) |
10 | 30 |
· Design Spec |
· 生成设计文档 |
10 | 20 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 | 20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
10 | 20 |
· Design |
· 具体设计 |
20 | 20 |
· Coding |
· 具体编码 |
100 | 150 |
· Code Review |
· 代码复审 |
20 | 30 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
50 | 100 |
Reporting |
报告 |
20 | 40 |
· Test Report |
· 测试报告 |
30 | 40 |
· Size Measurement |
· 计算工作量 |
10 | 10 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
5 | 15 |
合计 |
515 | 780 |
需求说明:
WordCount的需求可以概括为:对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。
1、基础功能:
-c:输出字符,
-l:输出代码行,
-w:输出单词,
-o:输出
2、 扩展功能:
-a:输出代码行/空行/注释行,
-s:递归处理文件,
-e:停用词表,
解题思路:
1、java实现,但需要转成exe在cmd下输入命令执行,所以流程是:编码(.java)-->Export(.jar)-->exe4j(.exe)
2、java里有static void main(String[] args),里面的args就是cmd下的命令数组,比如输入-c -l -w file.c(空格隔开),那么args数组长度为4
3、对args数组进行遍历分析,找出输入命令和文件名,比如-c -l -w -a 后面跟的是输入文件名,-s后面会跟*.c之类的通配文件,-e后面会跟停用词表stoplist.txt,-o接输出文件result.txt
这里识别出命令和文件后,会再对文件分析,比如-s ./WordCount/*.c,需要截取出文件的上一层(相对)路径./WordCount和后缀.c,方便后续递归文件夹下的.c文件
4、将所有的统计封装成一个函数:public void command(String[] args,String inputFile,String outputFile,WordCount WC)
5、创建一个WordCount类,里面的属性有字符数,单词数,行数,代码行,空行,注释行,如果没有出现-s:则只实例化一个对象WordCount,调用一次command函数,输出前面的结果,如果出 现 -s:即递归处理文件夹下面的*.c文件(当然*.txt,*.doc文件也是可以的),就声明多个WordCount对象,循环对对象属性进行赋值。如果需要输出就调用get和set方法获取属性值。
6、递归处理文件:根据相对路径递归寻找文件夹下的后缀文件。
程序设计实现:
类:
public class WordCount{}
函数方法设计:
WordCount(int,int,int,int,int,int)是构造函数;get和set是MyEclipse自动生成的的getter和setter方法,main(string [ ])是程序入口,分析判断指令格式;command(String [ ],String,String,WordCount)执行指令,返回相应指令的统计值;wc(String,String)对输入文件进行统计;inStop(String,String[ ])判断单词是否在停用词表内;getFile(File)递归获取文件。
代码说明:
1、执行命令:需要输出的有-c,-w,-l,-a,判断指令,直接暴力循环,优化日后再说。
//命令执行,根据命令输出数据到屏幕和outputFile中
public void command(String[] args,String inputFile,String outputFile,WordCount WC)throws IOException{
String outResult="";
inputFile=inputFile.substring(inputFile.lastIndexOf("\\")+1, inputFile.length());
for(int i=0;i<args.length;i++){
if(args[i].equals("-c"))
outResult=outResult+inputFile+",字符数:" + WC.getCharCount()+"\r\n";
}
for(int i=0;i<args.length;i++){
if(args[i].equals("-w"))
outResult=outResult+inputFile+",单词数:" + WC.getWordCount()+"\r\n";
}
for(int i=0;i<args.length;i++){
if(args[i].equals("-l"))
outResult=outResult+inputFile+",行数:" + WC.getLineCount()+"\r\n";
}
for(int i=0;i<args.length;i++){
if(args[i].equals("-a"))
outResult=outResult+inputFile+",代码行/空行/注释行:"+WC.getCodeCount()+","
+WC.getSpaceCount()+","+WC.getNoteCount()+"\r\n";
}
//写数据到outputFile
System.out.println(outResult);
File writename = new File(outputFile);
writename.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(writename,true));
out.write(outResult);
out.flush();
out.close();
}
2、统计功能字符数、单词数、行数、代码行/空行/注释行
提一下代码行/空行/注释行
//统计功能字符数、单词数、行数、代码行/空行/注释行
public void wc(String inputFile,String stopFile) throws IOException{
String lineString = null;
String[] buffer=null; //文件每行
String[] buffer1 = null;//stoplist boolean isNote = false;
int notNote=0; //读取停用词表
if(useStop){
File dirr=new File(stopFile);
BufferedReader bff = new BufferedReader(new FileReader(dirr));
while((lineString=bff.readLine())!=null){
buffer1=lineString.split(",| ");
}
bff.close();
}
lineString = null; // 读取输入文件inputFile
File dir=new File(inputFile);
BufferedReader bf = new BufferedReader(new FileReader(dir));
while((lineString=bf.readLine())!=null){ //遇到 , 空格 就结束赋值
buffer=lineString.split(",| ");
for(int i=0;i<buffer.length;i++){ //使用停用词表则剔除词表内单词,不用则不踢
if(useStop){
if(!buffer[i].equals("")&&!inStop(buffer[i], buffer1)){
wordCount++;
}
}
else{
wordCount++;
} }
if(buffer.length!=1)
lineCount++; charCount+=(lineString.length()+1); lineString=lineString.trim();
//空行,一个字符的也算空行
if (lineString.matches("^[//s&&[^//n]]*$")||lineString.length()==1) {
spaceCount++;
}
//注释/*的开始
else if (lineString.startsWith("/*") && !lineString.endsWith("*/")||((lineString.startsWith("{/*")
||lineString.startsWith("}/*"))&&!lineString.endsWith("*/"))){
noteCount++;
isNote=true;
}
//没有遇到*/
else if(isNote&&!lineString.endsWith("*/")&&!lineString.startsWith("*/")) {
notNote++;
noteCount++;
}
//遇到*/
else if (isNote == true && (lineString.endsWith("*/")||lineString.startsWith("*/"))) {
noteCount++;
isNote=false;
}
//注释行
else if (lineString.startsWith("//")|| lineString.startsWith("}//")||lineString.startsWith("{//")||
((lineString.startsWith("{/*") ||lineString.startsWith("}/*")||lineString.startsWith("/*"))
&& lineString.endsWith("*/"))) {
noteCount++;
}
else{
codeCount++;
}
}
bf.close();
noteCount-=notNote;
codeCount+=notNote;
}
//判断是否在停用词表内
public static boolean inStop(String str,String[] buffer){
int count=0;
for(int i=0;i<buffer.length;i++){
if(str.equals(buffer[i])){
count++;
}
}
if(count>0)
return true;
else
return false;
}
4、遍历文件目录,如-s ./test/*.c则递归遍历./test目录下的.c文件
//遍历目录文件
public static List<File> getFile(File dir) {
List<File> files = new ArrayList<File>();
// 此文件下的所有文件和文件夹集合
File[] subs = dir.listFiles();
for (File file : subs) {
if (file.isFile() && file.getName().endsWith(endStr)) {
// 把获取到的后缀文件添加到集合中,可以是任何后缀文件
files.add(file);
} else if (file.isDirectory())
//如果是目录,就进行递归
files.addAll(getFile(file));
}
return files;
}
测试设计过程:
设计测试用例的思路是采用白盒测试的语句覆盖,尽可能把测试用例覆盖所有可能的程序语句,当然特别是分支语句,会多做测试,如-s的是否递归处理文件在我的程序中是一个分支语句
基本功能:
1、测试-c:输出file.c字符数
wc.exe -c file.c
2、测试-c、-w、-l:输出file.c字符数,单词数、行数 (当前根目录)
wc.exe -c -w -l file.c
3、测试-w 、-l 、-c:输出./testFile/file.c 字符数,单词数、行数 (根目录下其他路径,命令顺序)
wc.exe -w -l -c ./testFile/file.c
4、测试-c 、-l 、-w、-o:输出file.c字符数,单词数、行数、输出到文件resultAdd.txt
wc.exe -c -l -w file.c -o resultAdd.txt
扩展功能:
5、测试-a:输出file.c的代码行/空行/注释行
wc.exe -a file.c
6、测试-s、-a:输出根目录下所有.c文件的代码行/空行/注释行
wc.exe -s -a *.c
7、测试-e:测试停用词表stoplist.txt
wc.exe -w file.c -e stoplist.txt
8、测试-c、-w、-l 、-a、-o:输出file.c字符数,单词数、行数 、代码行/空行/注释行输出到result.txt
wc.exe -c -w -l -a file.c -o result.txt
9、测试-a、-s、-e:测试递归,代码行/空行/注释行,停用词表stoplist.txt
wc.exe -a -s ./testFile/*.c -e stoplist.txt
10、测试-c、-w、-l、-a、-e、-o:对不递归进行测试
wc.exe -c -w -l -a file.c -e stoplist.txt -o result.txt
11、测试-c、-w、-l、-a、-s、-e、-o:覆盖所有的指令测试
测试脚本
点击testScript.exe可以执行完11个测试用例,类似于批处理的方式,但只有一个进程,批处理测试用例。
下面是java代码,简单叙述一下思路:创建一个进程打开之前的wc.exe,逐行读取测试用例testCase.txt,一行是一条测试用例。
package test;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner; public class TestScript {
//进程p
static Process p;
public static void main(String[] args) throws IOException{
String lineString=null;
File dirr=new File("testCase.txt"); //测试用例文件
if(dirr.exists()){
BufferedReader bff = new BufferedReader(new FileReader(dirr));
while((lineString=bff.readLine())!=null){
//非空行执行测试用例
if(!lineString.trim().matches("^[//s&&[^//n]]*$")){
System.out.println(lineString);
command(lineString);
}
}
bff.close();
}else{
System.out.println("没有该测试文件");
} Scanner sc = new Scanner(System.in);
String scc=sc.nextLine();
} public static void command(String cmd){
Runtime run = Runtime.getRuntime();//返回与当前 Java 应用程序相关的运行时对象
try {
p = run.exec(cmd);// 启动另一个进程来执行命令
BufferedInputStream in = new BufferedInputStream(p.getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
while ((lineStr = inBr.readLine()) != null)
System.out.println(lineStr);
if (p.waitFor() != 0) {
if (p.exitValue() == 1)
System.err.println("命令执行失败!");
}
inBr.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
} }
参考链接:
WordCount--实现字符,单词,代码统计的更多相关文章
- 软件工程 wc.exe 代码统计作业
软件工程 wc.exe 代码统计作业分享 1. Github 项目地址 https://github.com/EdwardLiu-Aurora/WordCount 更好地阅读本文,可点击这里 基本要求 ...
- WC 代码统计 java
GitHub地址 项目需求 实现一个wc统计程序,可以对文本进行相关功能的统计与分析 基本功能 -c 统计字符数 -w 统计文件词数 -l 统计行数 扩展功能 -s 递归搜索目录下面的文件 -a 返回 ...
- Spark学习笔记1——第一个Spark程序:单词数统计
Spark学习笔记1--第一个Spark程序:单词数统计 笔记摘抄自 [美] Holden Karau 等著的<Spark快速大数据分析> 添加依赖 通过 Maven 添加 Spark-c ...
- python 练习(一)代码统计工具的实现
最近部门成立了一个python学习小组,旨在让大家在做项目中开始成长起来,于是老大就给布置了第一个小任务:代码统计工具,具体的需求如下: 需求: . 能够统计指定目录下C++程序的代码行数. . C+ ...
- Python实现代码统计工具——终极加速篇
Python实现代码统计工具--终极加速篇 声明 本文对于先前系列文章中实现的C/Python代码统计工具(CPLineCounter),通过C扩展接口重写核心算法加以优化,并与网上常见的统计工具做对 ...
- Python代码统计工具
目录 Python代码统计工具 声明 一. 问题提出 二. 代码实现 三. 效果验证 Python代码统计工具 标签: Python 代码统计 声明 本文将对<Python实现C代码统计工具(一 ...
- Python实现C代码统计工具(三)
目录 Python实现C代码统计工具(三) 声明 一. 性能分析 1.1 分析单条语句 1.2 分析代码片段 1.3 分析整个模块 二. 制作exe Python实现C代码统计工具(三) 标签: Py ...
- Atitit. . 软件命名空间与类名命名单词的统计程序设计v2
Atitit. . 软件命名空间与类名命名单词的统计程序设计v2 1. 要实现的目标1 1.1. Camel字符串模式的分词处理1 1.2. 多个大写的处理1 1.3. 数字与字幕的分离1 1.4. ...
- 【学习笔记】C#中HashTable和快速排序的用法,从单词频率统计小程序写起
先瞎扯点别的.进入这个神圣的地方总需要些鞭策,阿西巴,我是被鞭策进来摆摊的程序猿.软件工程老师说,写程序,发博客,就来博客园.这是个号召力很强的口号.最近看网络营销 搜索引擎优化的书多一些,只能说王老 ...
- Java实现 蓝桥杯VIP 算法提高 不同单词个数统计
算法提高 不同单词个数统计 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,输入一个句子,然后统计出这个句子当中不同的单词个数.例如:对于句子"one little t ...
随机推荐
- 机器学习_第三季_Series
这一节没讲啥技术知识, 我就简单的罗列一下, 与numpy相似 1. 导入csv文件 import pandas as pdfandango = pd.read_csv("fandango_ ...
- sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set 的解决办法
Linux新建用户 ,sudo报错: sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set 解决办法:重置一下s ...
- sql query skill
https://www.w3resource.com/sqlite/sqlite-select-query-statement.php /* SELECT ChipID FROM "tb_X ...
- Lucas定理的运用及组合数奇偶性的判断
组合数奇偶性的判断 对于C(n,k),若n&k == k 则c(n,k)为奇数,否则为偶数. 最直观的方法就是计算一下,然后看它的奇偶性:但是这个时间以及数据范围上都不允许: 另外一种方法就是 ...
- Spring Boot系列教程十:Spring boot集成MyBatis
一.创建项目 项目名称为 "springboot_mybatis_demo",创建过程中勾选 "Web","MyBatis" ...
- 某 游戏公司 php 面试题
1.实现未知宽高元素的水平垂直居中,至少两种方法. <div, class="father"> <div class="son">< ...
- Windows计划任务无法写Log的问题
参照:https://www.cnblogs.com/jonezzz/p/10364153.html 使用WIndows计划任务去执行Exe文件时无法写Log,而Exe双击执行就能写Log,这是由于计 ...
- golang跨平台编译
// 目标平台linux 64 SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build //目标平台windows SET CGO_ENA ...
- (十一)mybatis之整合ehcache缓存
一.二级缓存 大家都知道使用mybatis就要先获取sqlsessionfactory,继而使用sqlsession来和数据库交互,每次只需要使用sqlsession对象提供的方法就好,当我们需要第一 ...
- (三)mybatis之通过接口加载映射配置文件
1.1 需求 通过(二)在全局配置文件 mybatis-configuration.xml 通过 <mappers> 标签来加载映射文件,那么如果我们项目足够大,有很多映射文件呢,难道我 ...