《构建之法》——第四次作业

第四次作业——结对编程

这个作业要求在哪里:第四次作业要求

Github项目地址:Wordcount

伙伴作业地址:iron-man

PSP表格:

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 15

 30

· Estimate

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

 30

 30

Development

开发

 360

 360

· Analysis

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

 60

 90

· Design Spec

· 生成设计文档

 45

 45

· Design Review

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

 60

 60

· Coding Standard

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

 60

 90

· Design

· 具体设计

 60

 60

· Coding

· 具体编码

 300

 300

· Code Review

· 代码复审

 60

 60

· Test

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

 60

 30

Reporting

报告

 30

 30

· Test Report

· 测试报告

 30

 30

· Size Measurement

· 计算工作量

 30

 45

· Postmortem & Process Improvement Plan

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

 30

 45

 

合计

 1230

 1305

 

解题思路 

  刚得到题目,分析它的难易程度时,发现查找到单词以及词组运用正则运算来匹配的话,会匹配到单词前面的分割符,所以就if语句来进行判断。由于c#掌握的不是很熟练,在csdn博客上查找了文件读取,字符分割及拼接,正则匹配的符号

 

设计实现过程

  首先main函数来获取参数,并传递给ReadTxt函数,Readtxt函数调用wordnumber函数来构建分割字符数组,并且得到字符串数组;传递给wordn,wordn函数将其整合成两个单词列表,

将sdx列表传给wordcount来统计词组,最后又回到readtxt输出到文件中。

将sd列表传给listdo函数统计单词出现的次数,然后又交给chosewords函数排序,最后在readtxt函数输出到文件中。

把简单的功能设计出来了,把统计行数、统计字符数放在了firstcount函数里。最后也是在在readtxt函数输出到文件中。

 

 代码规范

   命名规范,不能简写或用首字母代替。关键地方一定要注释,把函数的作用,参数的含义都注释出来。

 

 代码说明

   函数WordN(string[] ma,int h)作用是:将分割文件数据字符串得到的字符列表。

public static List<string> WordN(string[] ma,int h)
        {
            
            List<string> sd = new List<string>();

            List<string> sdx = new List<string>();//建立一个存储词组的列表
            int i = 0;
            foreach (string s in ma)               //遍历集合中每个单词
            {
               if(s!=="")
{
                if(s.Length<4)
                {
                    sdx.Add("!no");
                }
                else
                {
                    int j = 1;
                    for (i = 0; i < 4; i++)
                    {
                        if (((s[i] >= 'a') && (s[i] <= 'z')) || ((s[i] >= 'A') && (s[i] <= 'Z')))
                        {
                        }
                        else
                        {
                            j = 0;
                            break;
                        }
                    }
                    if (j == 1)
                    {
                        string s2 = s.ToLower();
                        sd.Add(s2);
                        sdx.Add(s);
                        
                        
                    }
                    else
                    {
                        sdx.Add("!no");
                    }

                }
}
               
            }

sdx.Add("!no");
if (h == 0) return sd; else return sdx; }

  函数wordcount作用是:将函数wordn返回的字符串列表sdx,进行词组统计,将每一个词组都先后存入字符串列表ac中,然后返回ac

public static List<string> WordsCount(List<string> sdx,int n)
        {
            List<string> ad = new List<string>();
            int i = 0;
            List<string> ac = new List<string>();

            foreach (string s in sdx)
            {
                if(s=="!no")
                {
                    while(i>=n)
                    {
                        string ae="";
                        int j = 0;
                        foreach (string af in ad)
                        { 
                            ae+=af+" ";
                            j++;
                        if(j ==n)
                            {
                                ac.Add(ae);
                                break; 
                            }
                        }
                        ad.RemoveAt(0);
                        i--;
                    }
                    ad.Clear();
                    i = 0;
                }
                else
                {
                    ad.Add(s);//这是一个大的词组
                    i++;
                }

            }

            return ac;
        }

  函数readtext的作用是:将词组和单词和字符数,行数,单词数,输入到指定文件夹。

public static void ReadTxt(string path,string outpath,int n,int number,int a,int b)
        {


            

            Dictionary<string, int> e = new Dictionary<string, int>();//筛选后的词典

            StreamReader sr = new StreamReader(path, Encoding.utf8);
            string restOfStream = sr.ReadToEnd();


 

 
if (outpath != "out")
            {
                
                StreamWriter sw = new StreamWriter(outpath, false);//true表示追加
                sw.WriteLine("characters: " + a);
                sw.WriteLine("words: " + WordN(WordNumber(restOfStream), 0).Count());
                sw.WriteLine("lines: " + b);

                //输出单词
                if (number > 0)
                {
                    e = Chosewords(Listdo(WordN(WordNumber(restOfStream), 0)), number);
                    foreach (string s in e.Keys)
                    {

                        sw.WriteLine("<" + s + ">: " + e[s]);
                    }
                }
                if (n > 0)
                {

                    List<string> ac = WordsCount(WordN(WordNumber(restOfStream), 1), n);
                    
                    for (int k=0;k<ac.Count();k++)
                    {
                        if(ac[k] != "!no")
                        { 
                        string xs = ac[k];

                        sw.Write(xs);
                        int numa = 0;
                        for(int u=0;u<ac.Count();u++)
                        {
                            if (ac[u] == xs)
                            {
                                ac[u] = "!no";
                                numa++;
                            }
                        }
                        
                        sw.WriteLine(": " + numa);
                        }
                    }
                   
                }
                
                sw.Flush();
                sw.Close();
            }

        }

  main函数是提供readtext函数需要的参数

static void Main(string[] args)
        {
               string p ="in";//输入文件路径
                string q="out";//输出文件路径
                int n=0;//词组长度
                int number=0;//输出单词个数
                for (int i=0;i<args.Length;i++)
                {
                    switch (args[i])
                    {
                        case "-i":p = args[i + 1];break;
                        case "-o": q = args[i + 1]; break;
                        case "-m": n=int.Parse(args[i+1]); break;
                        case "-n": number= int.Parse(args[i+1]); break;
                    }
                    i++;
                }
                
            


            //计算字符数汉字除外
            int a = FirstCount(p,0);
            //计算非空行数
            int b = FirstCount(p,1);
            //输出到目标文件
            ReadTxt(p,q,n,number,a,b);
           


        }

错误处理并设计单元测试

 创建单元测试,这里只展示出错的函数测试

 单元测试没有通过,修改了源码,发现了很多新的问题

 

  第一个问题是读取文件时没有使用utf8编码,导致汉字占用了后面单词的空间,改变了单词的长度

 

  不过及时地找出了这个问题的原因,并且解决了

 

 

 

   然而解决完上面这个问题,新的问题又出现了,

 

 把字符串数组换行输出,发现数组存在空字符串

 

 最终测试通过

 

 效能分析

加入以下代码,进行效能分析

 

 

效能分析结果如下

 

做了很多次测试与更改,最终编译成功

 

f)  结对感受

从这次作业中可以感受到结对编程的魅力,1+1是大于2的,在这个过程中,两个人能够互相监督和学习,发现并指出对方的错误。多一个人就多一份力,虽然因为基础不一样可能不能很快达成共识,但是这个过程也是一种学习。在这次结对编程中也让我认识到了我基础的不足,感谢小伙伴的耐心指导。

 

posted @ 2019-10-14 09:41  kotofight  阅读(155)  评论(1编辑  收藏  举报