《构建之法》第四次作业——结对编程

博客开头

这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign
这个作业要求在哪里 https://www.cnblogs.com/harry240/p/11524113.html
github地址 https://github.com/zjc-123/WordCount/tree/master/201731062321
结对同学博客地址 https://www.cnblogs.com/9527abc/
结对同学学号 201731062321

 

 

 

 

结对过程

PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30

 40

· Estimate

· 估计这个任务需要多少时间

 45

 50

Development

开发

 900

 1080

· Analysis

· 需求分析 (包括学习新技术)

 70

 90

· Design Spec

· 生成设计文档

 20

 20

· Design Review

· 设计复审 (和同事审核设计文档)

 30

 45

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 40

 30

· Design

· 具体设计

 60

 70

· Coding

· 具体编码

 540

 660

· Code Review

· 代码复审

 60

 90

· Test

· 测试(自我测试,修改代码,提交修改)

 120

 180

Reporting

报告

 60

 100

· Test Report

· 测试报告

 60

 60

· Size Measurement

· 计算工作量

 20

 20

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 25

 20

 

合计

 1125

 1395

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

解题思路

1、基本功能

      当阅读完项目需求说明后,我们的第一反应就是题目太长。经过讨论,我们觉得在此次的题目中有四个基本功能:一是统计整个文件的行数;二是统计文件的字符数(包括空格、换行符、标点);三是统计单词频率;四是输出单词长度有效词数。先是将题目要求的功能实现之后,再去考虑代码的规范优化。

 1、ReadWord.cs类:用于统计单词出现频率和计算指定单词长度的单词数。

 2、ReadChar.cs类:用于统计文件的行数和字符个数。

 3、program.cs:获取命令进行相应操作。

 4、通过switch(args[i])解析命令

2、程序大致流程图

部分实现代码

1、统计字符数和行数

- 正则表达式统计字符数和行数

string str = File.ReadAllText(path);

StreamWriter sw = File.AppendText(outpath);

int hz = Regex.Matches(str, @"[\u4E00-\u9FFF]").Count;//汉字

int en = str.Length;//字符

int num = Regex.Matches(str, @"\d").Count;//数字

int hang = Regex.Matches(str, @"\r").Count + 1;//行数

Console.WriteLine("汉字个数={0}\n字符个数(包括空格、标点、换行符)={1}\n数字个数={2}\n行数={3}", hz, en, num, hang);

2、统计单词频率和字典排序

- 利用正则表达式划分单词,用Dictionary的key和value记录单词和出现频率并进行排序

string paths = File.ReadAllText(path);

StreamWriter sw = File.AppendText(outpath);

Dictionary<string, int> frequencies = new Dictionary<string, int>();

frequencies = new Dictionary<string, int>();

string[] words = Regex.Split(paths, @"\W");

foreach (string word in words)

{

if (frequencies.ContainsKey(word))

{

frequencies[word]++;

}

else

{

frequencies[word] = 1;

}

if (word.Length < 4)

{

frequencies.Remove(word);

}

}

Dictionary<string, int> ff = frequencies.OrderByDescending(o ⇒ o.Value).ThenBy(p ⇒ p.Key).ToDictionary(p ⇒ p.Key, o ⇒ o.Value);//利用key和value排序

int count = 0;

Dictionary<string, int>.Enumerator hh = ff.GetEnumerator();

while (hh.MoveNext())

{

if (Len.Equals(hh.Current.Key.Length))

count = count + hh.Current.Value;

}

Console.WriteLine("文件中长度为" + Len + "的单词数:" + count + "个");

 

-利用dictionary中的key和value进行排序

Dictionary<string, int> ff = frequencies.OrderByDescending(o ⇒ o.Value).ThenBy(p ⇒ p.Key).ToDictionary(p ⇒ p.Key, o ⇒ o.Value);//利用key和value排序

代码互审

      我们通过代码互审、代码互测揪出了一批bug,改正了很多错误的地方。有些是不影响代码的运行,但在输入一些字符后程序就退出或者出现异常了。特别严重的是文件位置字符串的输入,老是出现异常或者是null的问题,找不到路径的文件,后续的改进:我们增加了对输入的文件的路径字符串的限定和判断,这样就大大增加了程序的可靠性。又比如:在输出相应单词长度的字符的需求时,忘了限制字符串的长度,导致输出了一大串数据。
      互审感悟:通过代码互审阶段,我们发现了很多自己没有发现的问题, 不同的人通过不同的方式、输入不同类型的数据进行测试,就会测出一些程序上的漏洞,大的漏洞甚至会影响程序的运行和输出错误的结果。这些都是自己一个人编程无法发现,也无法解决的问题。所以结对编程在小规模项目中应用的好处是显而易见的。

单元测试以及性能

对其中的三个方法进行测试

 性能测试

     可见wordCount.ReadWord.ReadW 占用百分比最大,优化主要以这个为主,对代码进行优化,减少代码间的重复调用,减少循环的调用,降低耦合等。

代码运行展示

1. 在控制台运行

 2.在命令行操作

收获和感悟

      在上本门课程之前,结对编程对我们来说是一个完全陌生的事务。在本次作业中尝试着使用结对编程这种模式来完成项目,渐渐发现了其在小规模项目和在我们学生学习中的好处。本次和队友结对的过程十分愉快,本来以为这种模式会浪费时间,但实际操作过程中发现这种模式却大大提高了效率。一开始读题目的时候感觉太长,我们将题目分解,画出流程图,分析解题思路,不到一个小时就大致确定了解题方法。如果两个人分开做,不使用结对编程,是完全不可能这么快完成的。真的是集思广益呀!再就是每个人都会有擅长的部分和不擅长的部分,在结对编程的过程中,我们互相学习,取长补短,使得自身编程能力也得到了很大的提升。最后就是不同的人对程序有不同的测试方法,会输入不同类型的测试数据进行测试,这样揪出了一批自己一个人很难甚至不可能发现的问题。总而言之,此次结对编程,我们合作得十分愉快,真正体验到了1+1>2!

参考资料

1.C#文本文件(.txt)读写

2.深入理解C#   第三章   用Dictionary来统计文本中的单词数

3.C#中Dictionary排序方式

posted on 2019-10-14 16:22  月隐星归  阅读(124)  评论(1编辑  收藏  举报