第三次作
Github项目地址:https://github.com/Roheeeee/WordCount.git
伙伴的地址:https://www.cnblogs.com/Xyk1017/p/10660322.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#,比如判断是否为有效单词时,需要用到正则表达式,按照字典排序时需要用Dictionary。
我们的思路是:先判断输入的命令行是否合法,统计字符数、单词数、行数以及统计单词的频率等功能用一个基本功能BaseCount函数来实现,再用一个拓展功能函数实现词组统计和自定义输出,最后在主函数中进行调用。
4.设计实现过程
这个博客对于单元测试的讲解很到位,简单易懂,可供参考:https://www.cnblogs.com/KevinMO/articles/5657747.html
整个代码共一个类,分为三个函数和一个主函数,三个函数分别为审查输入命令、统计基本功能实现、保存输出结果以及在主函数分别进行调用。
5.代码规范及代码互审情况
(1)命名:使用英文,且命名要符合该类或方法的具体功能描述。每个单词的第一个字母最好大写,且不使用缩写已经下划线。
(2)缩进4个空格。
(3)每行只写一条语句。
(4)注释:根据需要添加注释。
(5)在一个类中,各个方法需用一个空行隔开。
我们在编码之前就制定好了代码规范,各自完成编码后对照制定的编码规范也进行了代码的自审,所以代码互审时并没有太多的规范方面的问题,主要是编码思想和逻辑方面的问题。
性能分析图
代码说明
判断输入命令是否合法
private string[] sParameter; private int iCharcount; private int iWordcount; private int iLinecount; //定义文件名、参数数组、字符数、单词数、总行数 char[] symbol = { ' ', '\t', ',', '.', '?', '!', ':', ';', '\'', '\"', '\n', '{', '}', '(', ')', '+', '-', '*', '=' }; //定义一个字符数组 public void Operator(string[] sParameter) //判断输入进去的命令是否合法 { this.sParameter = sParameter; foreach (string s in sParameter) { if (s == "-c" || s == "-w" || s == "-l") { break; } else { Console.WriteLine("参数{0}不存在", s); break; } } }
功能实现
1 统计字符数、行数以及单词数
对文件进行读取,依次判断字符数、行数,单词数(即Listt数组中的元素个数)
利用文件读取每行的数据,并记录在ILine数组中,再对ILine数组进行分割(以空格为分割标记),把得到的每个单词存储到List数组中:
public void Word(List<string> ls) { string[] IWord1 = new string[] { }; string[] ILine = File.ReadAllLines(@"E:\AchaoCalculator\foruc\ConsoleApplication2\ConsoleApplication2\bin\Debug\wordcount.txt"); for (int i = 0; i < ILine.Length; i++) { IWord1 = ILine[i].Split(' '); for (int j = 0; j < IWord1.Length; j++) { ls.Add(IWord1[j]); } } }
private void BaseCount(List<string> ls) { try { int sChar; int charcount = 0; int linecount = 0; FileStream fs = new FileStream(@"E:\AchaoCalculator\foruc\ConsoleApplication2\ConsoleApplication2\bin\Debug\wordcount.txt", FileMode.Open, FileAccess.Read); // 打开文件(运用指令) StreamReader sr = new StreamReader(fs); while ((sChar = sr.Read()) != -1) { charcount++; // 统计字符数 if (sChar == '\n') { linecount++; // 统计行数 } } iCharcount = charcount; iWordcount = ls.Count-1; iLinecount = linecount + 1; sr.Close(); } catch (IOException ex) { Console.WriteLine(ex.Message); return; } }
利用SaveResult( )函数来实现对行数、字符数以及单词数的文件读取写入操作;以及对文件中内容按字典序排序;以及对频率前十的单词进行统计:
public void SaveResult(List<string> ls) //将输出结果保存数据到该地址下的resul.text中 { FileStream fs = new FileStream(@"E:\AchaoCalculator\foruc\ConsoleApplication2\ConsoleApplication2\bin\Debug\result.txt",FileMode.Create,FileAccess.Write ); StreamWriter sw = new StreamWriter(fs); foreach (string a in sParameter) { if (a == "-c") sw.WriteLine("字符数:{0}",iCharcount); if (a == "-w") sw.WriteLine("单词数:{0}", iWordcount); if (a == "-l") sw.WriteLine("行数:{0}", iLinecount); } sw.WriteLine("文件中包含单词有:"); for (int j = 0; j < ls.Count; j++) { sw.WriteLine(ls[j]); } ls.Sort(); //排序 sw.WriteLine("按字典序排序之后:"); for (int j = 0; j < ls.Count; j++) { //按小写输出 sw.WriteLine(ls[j].ToLower()); } int max = -1, k = 0; List<string> temp = new List<string>(); int maxt = 0; int[] count = new int[ls.Count+10]; for (int i = 0; i < ls.Count; i++) { count[i]for(int j = 0; j < ls.Count; j++) { if (i != j && ls[i].Equals(ls[j])) { count[i]++; } } } // for (int i = 0; i < ls.Count; i++) // { // sw.WriteLine(ls[i]+" "+count[i]); // } for (int i = 0; i < count.Length; i++) { if (count[i] > max) { max = count[i]; maxt = i; } } temp.Add(ls[maxt]); // sw.Write("max=" + max); int t = 0, c = 0 ; sw.WriteLine("文件中单词出现频率最高的10个单词:"); sw.WriteLine("<" + ls[maxt] + ">:" + count[maxt]); while (t < 9) { for (int i = 0; i < ls.Count; i++) { if (t == 9) break; c = 0; for (int j = 0; j < temp.Count; j++) { if (temp[j] == ls[i]) c = 1; } if (c == 0) { if (count[i] == max) { sw.WriteLine("<" + ls[i] + ">:" + count[i]); t++; temp.Add(ls[i]); } } } max--; } sw.Close(); fs.Close(); Console.ReadKey(); }
主函数运行:
运行结果:
先写一个“wordcount”记事本文件,内容如下:
执行后的结果:
1 统计行数、字符数以及单词数
2 排序前的所有单词:
长省略……
排序后的单词:
长省略……
3 频率前十的单词:
提交代码至git
将代码提交至github时,总共签入了三次,第一次是基础功能的签入,第二次是拓展功能的签入,最后一次是编译成功后签入。
心路历程与收获以及结对感受