第三次作业
一、相关地址
| Github项目地址 | 地址1 |
| 作业地址 | 地址2 |
二、PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
| Planning | 计划 | 40 | 30 |
| --Estimate | 估计任务需要的时间 | 40 | 30 |
| Development | 开发 | 1390 | 1540 |
| --Analysis | 需求分析 | 60 | 75 |
| --Design Spec | 生成设计文档 | 60 | 50 |
| --Design Review | 设计审计 | 60 | 65 |
| --Coding Standard | 代码规范 | 60 | 55 |
| --Design | 具体设计 | 60 | 75 |
| --Coding | 具体编码 | 850 | 900 |
| --Code Review | 代码复审 | 180 | 200 |
| --Test | 测试 | 60 | 120 |
| Reporting | 报告 | 80 | 110 |
| --Test Report | 测试报告 | 15 | 35 |
| --Size Measurement | 计算工作量 | 45 | 45 |
| --Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 20 | 30 |
| 总计 | 1510 | 1680 |
三、项目需求说明
1.代码流程

2.实现基本功能
- 功能分析:
本次作业需要实现一下几项功能,个人用到四个类以及四个函数,分别用于实现统计字符数、统计单词数
以及输出对应词频和统计行数,最后增加一个具有输出功能的类和函数。以下是部分功能及代码。
- 解题思路:
统计字符数--对文件内容逐个筛选,每遇到一个字符,count加一,直到返回-1结束并返回count值。
统计统计单词--运用if-else if-else语句对字符按照条件筛选,并放入两个字典中,再把字典中储存的单词
进行进一步筛选,统计出词频。
统计行数--逐个字符筛选,遇到换行符数值加一直到返回-1结束,返回结果数值。
- 统计字符数:
1 public int tjzf(string filename)//统计字符数 2 { 3 int zfcount = 0; 4 int zfchar = 0; 5 FileStream F = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 6 StreamReader S = new StreamReader(F); 7 while ((zfchar = S.Read()) != -1) 8 { 9 zfcount++; 10 } 11 F.Close(); 12 return zfcount - 6; 13 }
- 统计单词数以及输出词频:(由于本人代码比较繁琐,故此处只给出关键代码)
1 while ((zfchar = S.Read()) != -1) 2 { 3 if (x < 4) 4 { 5 if ((zfchar >= 'a' && zfchar <= 'z') || (zfchar >= 'A' && zfchar <= 'Z')) 6 { 7 strc = ((char)zfchar).ToString(); 8 str = str + strc; 9 x++; 10 } 11 else 12 { 13 continue; 14 } 15 } 16 else if (x >= 4) 17 { 18 if (zfchar >= '0' && zfchar <= '9' || (zfchar >= 'a' && zfchar <= 'z') || (zfchar >= 'A' && zfchar <= 'Z')) 19 { 20 strc = ((char)zfchar).ToString(); 21 str = str + strc; 22 } 23 else 24 { 25 x = 0; 26 if (D.ContainsValue(str) || D.ContainsValue(str.ToLower()) || D.ContainsValue(str.ToUpper())) 27 { 28 foreach (KeyValuePair<int, string> pair in D) 29 { 30 if (pair.Value.ToLower() == str.ToLower() && pair.Value.ToUpper() == str.ToUpper() && pair.Value == str) 31 { 32 temp++; 33 DD.Remove(str); 34 DD.Add(str.ToLower(), temp); 35 } 36 else 37 { 38 continue; 39 } 40 } 41 } 42 else 43 { 44 DD.Add(str, 1); 45 D.Add(dccount, str); 46 } 47 str = null; 48 strc = null; 49 dccount++; 50 } 51 } 52 }
- 统计行数:
1 public int tjhs(string filename)//统计行数 2 { 3 int hscount = 0; 4 int zfchar; 5 FileStream F = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 6 StreamReader S = new StreamReader(F); 7 while ((zfchar = S.Read()) != -1) 8 { 9 if (zfchar == '\n') 10 { 11 hscount++; 12 } 13 else 14 { 15 continue; 16 } 17 } 18 F.Close(); 19 return hscount - 2; 20 }
- 测试文件:

- 测试结果:

- 可优化部分
在进行统计单词的步骤中,可使用正则表达式进行筛选,可替代大段if-else if-else语句以及代码。
3.接口封装
1 public interface countchar 2 { 3 int tjzf(string filename);//统计字符数 4 int tjdc(string filename);//统计单词数并按照字典序输出词频 5 int tjhs(string filename);//统计行数 6 void dis(); //输出结果 7 }
4.增加新功能(部分代码)
1 if (x.Contains("-n") && x.Contains("-m") && x.Contains("-o")) 2 { 3 int words; 4 words = b.tjdc(filename); 5 Console.WriteLine("words:{0}", words); 6 int characters; 7 characters = a.tjzf(filename); 8 Console.WriteLine("characters:{0}", characters); 9 int lines; 10 lines = c.tjhs(filename); 11 Console.WriteLine("lines:{0}", lines); 12 } 13 else if (x.Contains("-m") && x.Contains("-o")) 14 { 15 int characters; 16 characters = a.tjzf(filename); 17 Console.WriteLine("characters:{0}", characters); 18 int lines; 19 lines = c.tjhs(filename); 20 Console.WriteLine("lines:{0}", lines); 21 }
四、代码复审
由于个人代码过于繁琐,故复审耗时较长,部分循环结构中的语句书写位置不对导致个人耗费大量时间去
重新看代码并逐步修改,部分知识点(例如字典)不熟练,因此需要查阅很多资料弥补不足,从而降低个人的
效率。
五、单元检测
- 测试代码:
1 string filename1 = @"D:\test1.txt"; 2 string filename2 = @"D:\test2.txt"; 3 string filename3 = @"D:\test3.txt"; 4 Assert.IsNotNull(filename1); 5 Assert.IsNotNull(filename2); 6 Assert.IsNotNull(filename3);
- 测试结果图:

六、性能分析
- 性能分析报告:程序中消耗最大的函数为主函数。(主函数主要调用dis函数,下面是主函数代码以及部分dis函数代码)
1 static void Main(string[] args) 2 { 3 display dd = new display(); 4 dd.dis(); 5 Console.ReadLine(); 6 }
1 A a = new A(); 2 B b = new B(); 3 C c = new C(); 4 string x; 5 Console.WriteLine("请输入文件名称:"); 6 string File = Console.ReadLine(); 7 string filename = @"D:\" + File; 8 Console.WriteLine("请输入操作内容:(-n:统计单词数;-m:统计字符数;-o:统计行数)以上可以混合输入 "); 9 x = Console.ReadLine(); 10 if (x.Contains("-n") && x.Contains("-m") && x.Contains("-o")) 11 { 12 int words; 13 words = b.tjdc(filename); 14 Console.WriteLine("words:{0}", words); 15 int characters; 16 characters = a.tjzf(filename); 17 Console.WriteLine("characters:{0}", characters); 18 int lines; 19 lines = c.tjhs(filename); 20 Console.WriteLine("lines:{0}", lines); 21 } 22 else if (x.Contains("-m") && x.Contains("-o")) 23 { 24 int characters; 25 characters = a.tjzf(filename); 26 Console.WriteLine("characters:{0}", characters); 27 int lines; 28 lines = c.tjhs(filename); 29 Console.WriteLine("lines:{0}", lines); 30 }

七、异常处理
在编写代码的过程中,由于个人对字典不够了解,尝试用多个数组完成功能,但是总会遇到数组越界
的问题,由于本人代码较复杂,于是选择具体学习下字典,并且个人感觉效果很好。
八、个人感受
在整个过程中,由于基础知识不够牢固,其中大部分时间花费在编写和复审代码上,语句之间的逻辑
关系不够明确,思路较为繁琐,用大量的代码才能实现基本功能,个人能力不足。庆幸体验这一过程。
浙公网安备 33010602011771号