第三次作业
Github项目地址:https://github.com/Roheeeee/WordCount.git
结对伙伴作业地址:https://www.cnblogs.com/rikoprpo/p/10660241.html
1.两人讨论的照片:
2.结对的PSP表格
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
30 |
60 |
· Estimate |
· 估计这个任务需要多少时间 |
540 |
780 |
Development |
开发 |
420 |
670 |
· Analysis |
· 需求分析 (包括学习新技术) |
60 |
90 |
· Design Spec |
· 生成设计文档 |
60 |
60 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 |
60 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
15 |
10 |
· Design |
· 具体设计 |
60 |
75 |
· Coding |
· 具体编码 |
75 |
240 |
· Code Review |
· 代码复审 |
60 |
75 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
60 |
60 |
Reporting |
报告 |
120 |
110 |
· Test Report |
· 测试报告 |
60 |
60 |
· Size Measurement |
· 计算工作量 |
20 |
20 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
40 |
30 |
|
合计 |
540 |
780 |
3.解题思路描述
拿到题目之后最开始的感觉是这次的题目有点复杂,需要处理很多细节问题,开始的时候思路有点乱,后来与搭档的同学一起讨论后,逐渐有了思路,但由于对C#不太熟练,我们查资料的过程比较漫长,相当于重新学习了一次C#,遇到的一些问题,如判断单词是否为有效单词、如何字典排序等等,都经过查找资料和询问同学慢慢解决。
我们的思路是:先判断输入的命令行是否合法,统计字符数、单词数、行数以及统计单词的频率等功能用一个基本功能BaseCount函数来实现,再用一个拓展功能函数实现词组统计和自定义输出,最后在主函数中进行调用。
4.设计实现过程
整个代码共一个类,分为三个函数和一个主函数,三个函数分别为审查输入命令、统计基本功能实现、保存输出结果以及在主函数分别进行调用。
单元测试:
这位大佬的博客对于单元测试的讲解很到位,简单易懂,可供参考:https://www.cnblogs.com/KevinMO/articles/5657747.html
5.代码规范及代码互审情况
(1)命名:使用英文,且命名要符合该类或方法的具体功能描述。每个单词的第一个字母最好大写,且不使用缩写以及下划线。
(2)缩进4个空格。
(3)每行只写一条语句。
(4)注释:根据需要添加注释。
(5)在一个类中,各个方法需用一个空行隔开。
我们在编码之前就制定好了代码规范,各自完成编码后对照制定的编码规范也进行了代码的自审,所以代码复审时并没有太多的规范方面的问题,主要是编码思想和逻辑方面的问题。
6.性能分析图
发现在Main函数中CPU使用率占比较高。
7.代码说明
判断输入命令是否合法
1 public class Wordcount 2 { 3 private string[] sParameter; 4 private int iCharcount; 5 private int iWordcount; 6 private int iLinecount; //定义文件名、参数数组、字符数、单词数、总行数 7 char[] symbol = { ' ', '\t', ',', '.', '?', '!', ':', ';', '\'', '\"', '\n', '{', '}', '(', ')', '+', '-', '*', '=' }; //定义一个字符数组 8 public void Operator(string[] sParameter) //判断输入进去的命令是否合法 9 { 10 this.sParameter = sParameter; 11 foreach (string s in sParameter) 12 { 13 if (s == "-c" || s == "-w" || s == "-l") 14 { 15 break; 16 } 17 else 18 { 19 Console.WriteLine("参数{0}不存在", s); 20 break; 21 22 } 23 } 24 }
功能实现
统计字符数、行数以及单词数
对文件进行读取,依次判断字符数、行数,单词数(即Listt数组中的元素个数)
利用文件读取每行的数据,并记录在ILine数组中,再对ILine数组进行分割(以空格为分割标记),把得到的每个单词存储到List数组中:
1 public void BaseCount(List<string> ls) 2 { 3 try 4 { 5 int sChar; 6 int charcount = 0; 7 int linecount = 0; 8 FileStream fs = new FileStream(@"D:\第三次作业\WordCount\WordCount\bin\Debug\input.txt", FileMode.Open, FileAccess.Read); // 打开文件(运用指令) 9 StreamReader sr = new StreamReader(fs); 10 while ((sChar = sr.Read()) != -1) 11 { 12 charcount++; // 统计字符数 13 if (sChar == '\n') 14 { 15 linecount++; // 统计行数 16 } 17 } 18 iCharcount = charcount; 19 iWordcount = ls.Count - 1; 20 iLinecount = linecount + 1; 21 22 sr.Close(); 23 } 24 catch (IOException ex) 25 { 26 Console.WriteLine(ex.Message); 27 return; 28 } 29 30 }
1 public void Word(List<string> ls) 2 { 3 4 string[] IWord1 = new string[] { }; 5 string[] ILine = File.ReadAllLines(@"D:\第三次作业\WordCount\WordCount\bin\Debug\input.txt"); 6 for (int i = 0; i < ILine.Length; i++) 7 { 8 IWord1 = ILine[i].Split(' '); 9 for (int j = 0; j < IWord1.Length; j++) 10 { 11 ls.Add(IWord1[j]); 12 } 13 } 14 }
利用SaveResult( )函数来实现对行数、字符数以及单词数的文件读取写入操作;以及对文件中内容按字典序排序;以及对频率前十的单词进行统计:
1 public void SaveResult(List<string> ls) //将输出结果保存数据到该地址下的resul.text中 2 { 3 FileStream fs = new FileStream(@"D:\第三次作业\WordCount\WordCount\bin\Debug\result.txt", FileMode.Create, FileAccess.Write); 4 StreamWriter sw = new StreamWriter(fs); 5 foreach (string a in sParameter) 6 { 7 if (a == "-c") 8 sw.WriteLine("字符数:{0}", iCharcount); 9 if (a == "-w") 10 sw.WriteLine("单词数:{0}", iWordcount); 11 if (a == "-l") 12 sw.WriteLine("行数:{0}", iLinecount); 13 } 14 sw.WriteLine("文件中包含单词有:"); 15 for (int j = 0; j < ls.Count; j++) 16 { 17 sw.WriteLine(ls[j]); 18 } 19 ls.Sort(); //排序 20 sw.WriteLine("按字典序排序之后:"); 21 for (int j = 0; j < ls.Count; j++) 22 { 23 //按小写输出 24 sw.WriteLine(ls[j].ToLower()); 25 } 26 int max = -1; 27 List<string> temp = new List<string>(); 28 int maxt = 0; 29 int[] count = new int[ls.Count + 10]; 30 for (int i = 0; i < ls.Count; i++) 31 { 32 count[i] = 1; 33 } 34 for (int i = 0; i < ls.Count; i++) 35 { 36 for (int j = 0; j < ls.Count; j++) 37 { 38 if (i != j && ls[i].Equals(ls[j])) 39 { 40 count[i]++; 41 } 42 } 43 } 44 for (int i = 0; i < count.Length; i++) 45 { 46 if (count[i] > max) 47 { 48 max = count[i]; 49 maxt = i; 50 } 51 } 52 temp.Add(ls[maxt]); 53 int t = 0, c = 0; 54 sw.WriteLine("文件中单词出现频率最高的10个单词:"); 55 sw.WriteLine("<" + ls[maxt] + ">:" + count[maxt]); 56 while (t < 9) 57 { 58 for (int i = 0; i < ls.Count; i++) 59 { 60 if (t == 9) break; 61 c = 0; 62 for (int j = 0; j < temp.Count; j++) 63 { 64 if (temp[j] == ls[i]) c = 1; 65 } 66 if (c == 0) 67 { 68 if (count[i] == max) 69 { 70 sw.WriteLine("<" + ls[i] + ">:" + count[i]); 71 t++; 72 temp.Add(ls[i]); 73 } 74 } 75 } 76 max--; 77 } 78 79 sw.Close(); 80 fs.Close(); 81 Console.ReadKey(); 82 }
运行截图:
8.提交代码至git
将代码提交至github时,总共签入了三次,第一次是基础功能的签入,第二次是拓展功能的签入,最后一次是编译成功后签入。
9.心路历程与收获以及结对感受
这次结对编程是之前从来没有用过的形式,通过与伙伴交流并解决问题,我们都学习到了对方的不同的思维模式以及对编码的不同观点,受到了很多启发,当然是1+1>2,虽然这次结对编程所耗费的时间远远超出了我们的预期,但最终我们都收获到了很多,对于C#的知识了解到了更多,对于github的操作也更加熟练,同时遇到的很多问题也能通过自己查阅资料得到解决。