第三次作业

                        结对编程WordCount

作业链接: https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2882
GIT仓库地址:  https://github.com/wangli20173106/WordCount
结对人员: 201731062318王力201731062315余希伦

1.结对项目PSP编写

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30

 20

· Estimate

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

 30

 20

Development

开发

 440

 370

· Analysis

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

 20

 20

· Design Spec

· 生成设计文档

 30

 40

· Design Review

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

 60

 40

· Coding Standard

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

 60

 40

· Design

· 具体设计

 30

 30

· Coding

· 具体编码

 180

 150

· Code Review

· 代码复审

 30

 30

· Test

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

 30

 20

Reporting

报告

90

 80

· Test Report

· 测试报告

 30

 30

· Size Measurement

· 计算工作量

 30

 20

· Postmortem & Process Improvement Plan

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

 30

 30

合计

560

 470

 小结:看到题目之后,仔细审题并看来作业要求,评分指标,明显感觉这次作业难度更大,我们首先两个人商量制定PSP,使得整个

项目过程清晰明了,可以更好的把控项目进度和花费时间,然后重新复习了一遍《面向对象编程C#》这本书,温习了C#,然后阅读了

助教小姐姐的类似博客,就开始设计结构,明确分工,提高了开发效率和软件质量。

2.代码互审

2.1:代码规范

1.程序总体逻辑结构清晰,注释简洁清楚,十分方便别人阅读并理解代码;

2.对C#的一些函数比较熟悉;                                                                                                                      

3.运用了正则表达式处理单词识别的问题;

4.代码整体布局风格统一,比较规范;

5.主函数不宜写太长

6.可以把实现不同功能的部分代码抽取出来用函数实现。

2.2:互审过程及问题

提前制定了代码规范,并且设计了程序运行的结构,使得写出来的代码格式清晰,各部分函数分工明确,

让人很容易读懂代码的内容,了解程序的运行过程。余希伦是领航员,我是驾驶员,参照《软件工程原理》

中结对编程模式,共同开发。 

3.设计

程序结构设计

 输入类设计

 

难点:单词计数类设计

 

输出类:

4.代码说明

Main()方法

Main()方法中调用TestMethod()方法,接着由TestMethod()依次调用program.DataInput();//输入program.FileRead(path);//文件读取

program.MainCount();//计数program.Output();//输出program.FileSave();

public void TestMethod()
        {
            program.DataInput();//输入
            program.FileRead(path);//文件读取
            program.MainCount();//计数
            program.Output();//输出
            program.FileSave();//生成文本文件
        }
        public void TestMethod(string l_path, string S_path, int num, int outNum)
        {
            path = l_path;
            number = num;
            outPutNum = outNum;
            s_path = S_path;
            program.FileRead(path);
            program.MainCount();
            program.Output();
            program.FileSave();
        }

  DataInput()

DataInput()方法写的方法和代码执行过程相对应,同时易于理解输入

void DataInput()
        {
            Console.WriteLine("输入读取文档路径:");
            path = Console.ReadLine();
            Console.WriteLine("输入想要输出的词组长度:");
            number = int.Parse(Console.ReadLine());
            Console.WriteLine("输出单词数量:");
            outPutNum = int.Parse(Console.ReadLine());
            Console.WriteLine("输出存储路径:");
            s_path = Console.ReadLine();

        

文件读写代码

void FileRead(string path)
        {
            StreamReader sr = new StreamReader(path, Encoding.Default);
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                Lines.Add(line);
            }
        }

核心代码:MainCount()

 这个方法用于判断单词字符,应该是最难的部分,为了方便理解,代码中有详细注释。

void MainCount()
        {
            int wordJudge = 0;//单词长度标记
            int MutiWords = 0;//判断目前是否为词组记录状态的标志变量
            int MutiWordsJudge = 0;//词组长度标记
            bool isWord = true;
            string _word = "";
            foreach (var str in Lines)
            {
                int lineJudge = 0;
                foreach (var word in str)
                {
                    //判断当前检测字符是否为空
                    if (word != ' ')
                    {
                        lineJudge++;
                        characters++;
                        //判断当前是否为单词检测状态,判断当前检测字符是否为字母
                        if ((isWord == true) && (((word >= 65) && (word <= 90)) || ((word >= 97) && (word <= 122))))//判断是否为字母内容
                        {
                            wordJudge++;
                            _word = _word + word;
                        }
                        else
                        {
                            //切换至非单词状态
                            if (wordJudge == 0)
                            {
                                isWord = false;
                                MutiWords++;
                            }
                            else
                            {
                                //判断当前是否为单词数字后缀
                                if ((wordJudge >= 4) && ((word >= 48) && (word <= 57)))
                                {
                                    _word = _word + word;
                                }
                                else
                                {
                                    //判断是否已经构成单词
                                    if (wordJudge >= 4)
                                    {
                                        WordAdd(_word);
                                        wordJudge = 0;
                                        _word = "";
                                    }
                                    //结束当前判断周期,重新切换至单词检测状态
                                    else
                                    {
                                        wordJudge = 0;
                                        _word = "";
                                        isWord = true;
                                        MutiWords = 0;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        MutiWordsJudge++;
                        //检测到空字符时结束当前判断周期,开启新周期
                        isWord = true;
                        MutiWords = 0;
                        //判断当前检测结果是否构成单词
                        if (wordJudge >= 4)
                        {
                            WordAdd(_word);
                            wordJudge = 0;
                            _word = "";
                        }
                        else
                        {
                            MutiWords++;
                            wordJudge = 0;
                            _word = "";
                            MutiWordsJudge = 0;
                        }
                        if ((MutiWords == 0) && (MutiWordsJudge == number))
                        {
                            MutiWordsAdd();
                            MutiWordsJudge = 0;
                        }
                    }
                }
                //在行末判断是否已构成单词
                if (wordJudge >= 4)
                {
                    WordAdd(_word);
                    wordJudge = 0;
                    _word = "";
                    if ((MutiWords == 0) && (MutiWordsJudge == number - 1))
                    {
                        MutiWordsAdd();
                        MutiWordsJudge = 0;
                    }
                }
                //判断当前行是否为有效行
                if (lineJudge != 0)
                {
                    lines++;
                }
            }
        }

  Output()

void Output()
        {
            List<string> words = program.WordSort();
            Console.WriteLine("字符:" + program.characters);
            SaveStrs.Add("字符:" + program.characters);
            Console.WriteLine("单词:" + program.Words.Count);
            SaveStrs.Add("单词: " + program.Words.Count);
            Console.WriteLine("行:" + program.lines);
            SaveStrs.Add("行:" + program.lines);
            int i = 0;
            //输出高频单词
            if (Words.Count < outPutNum)
            {
                for (; i < Words.Count; i++)
                {
                    foreach (var iword in Words)
                    {
                        if (words[i] == iword.text)
                        {
                            Console.WriteLine(iword.text + " " + iword.num);
                            SaveStrs.Add(iword.text + " " + iword.num);
                            break;
                        }
                    }
                }
            }
            else
            {
                for (; i < outPutNum; i++)
                {
                    foreach (var iword in program.Words)
                    {
                        if (words[i] == iword.text)
                        {
                            Console.WriteLine(iword.text + " " + iword.num);
                            SaveStrs.Add(iword.text + " " + iword.num);
                            break;
                        }
                    }
                }
            }
            //输出词组
            foreach (var word in MutipleWords)
            {
                Console.WriteLine(word.text + " " + word.num);
                SaveStrs.Add(word.text + " " + word.num);
            }
        }

运行效果:

5.测试过程

单元测试:

断点测试

 性能分析图

 

分析发现,Output()方法消耗最大,主要原因是在输出的时候运用了嵌套for循环。

异常及处理:

针对于文件输入时发生的错误。

6.上传代码

7.总结

 在这次结对编程项目中,最大的感受就是1+1>2,如果一个人做,难度比较大。正所谓:兄弟齐心,其利断金;尤其是在找bug

方面。而且制定了代码规范,两个人的代码都相互易读。包括在最初的结构设计上,刚开始两人各抒己见,经过一番商讨之后,

设计出了双方都满意且最优的结构,在这里结对编程的优势更为明显。

原文地址:https://www.cnblogs.com/wang20173/p/10651813.html