软件工程 结对项目-最长单词链

软件工程 结对项目-最长单词链

项目 内容
这个做业属于哪一个课程 软件工程课程
这个做业的要求在哪里 结对项目-最长单词链
我在这个课程的目标是 掌握现代软件工程的基本知识,与团队一块儿进行软件开发。
这个做业在哪一个具体方面帮助我实现目标 与另外一位同窗一块儿结对编程,初步体会了软件开发。

1.Github项目地址

Github项目地址node

2.PSP表格(预估开发耗费时间)

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20
·Estimate ·估计这个任务须要多少时间 20
Development 开发 1710
·Analysis ·需求分析(包括学习新技术) 20
·Design Spec ·生成设计文档 20
·Design Review ·设计复审(和同事审核设计文档) 20
·Coding Standard ·代码规范(为目前的开发制定合适的规范) 20
·Design ·具体设计 30
·Coding ·具体编码 1000
·Code Review ·代码复审 300
·Test ·测试(自我测试,修改代码,提交修改) 300
Reporting 报告 230
·Test Report ·测试报告 200
·Size Measurement ·计算工做量 10
·Postmortem & Process Improvement Plan ·过后总结,并提出过程改进计划 20
合计 1960

3.在结对编程中如何对接口进行设计

把计算最长链的函数单独写成一个Core类,在Core类中提供两个接口,int gen_chain_wordint gen_chain_char分别用于计算单词最多的链和字母最多的链,其余函数属性为private,隐藏在文件中,不能被其余东西调用。其余人在使用的时候只能经过gen_chain_wordgne_chain_char这两个接口来使用。git

4.计算模块接口的设计与实现过程

计算模块包含一个Core类,其中有两个可供外部调用的接口github

int gen_chain_word(char* words[], int len, char* result[], char head, char tail, bool enable_loop);

int gen_chain_char(char* words[], int len, char* result[], char head, char tail, bool enable_loop);

类中还有其余八个函数编程

void newnode(string word);

    void addtomap(node newword);

    void toforest();

    void next1(vector<int> forward, int root);

    void next2(vector<int> forward, int root);

    int findmostwords(char head, char tail);

    int findlongest(char head, char tail);

    int listlength(int index);

各函数之间的调用流程
函数调用流程微信

5.UML图

UML图

6.计算模块接口部分的性能改进。

(1)改进花费时间

改进计算模块性能所花费的时间:2小时。网络

(2)改进思路

第一个版本的程序中,不管面对什么状况,都会把有向图中的大大小小的全部链路都分出来,花费了大量的时间。
在不约束首位字母和只约束首字母的状况下,只按照各个根节点来生成最长的单词链。
在约束尾字母的状况下,再加入对尾字母的判断,生成更多的链。app

(3)性能分析图

性能分析图1
性能分析图2

(4)消耗最大的函数

根据分析结果看,消耗最大的函数是 listlength()函数
这个函数的功能是计算单词链字母的长度。
代码以下函数

int Core::listlength(int index)

{

    int sum = 0;

    int i = 0;

    for (i = 0; i < forest[index].size(); i++)

    {

        sum += map[forest[index][i]].wordlen;

    }

    return sum;

}

7.看Design by Contract, Code Contract的内容,描述这些作法的优缺点, 说明你是如何把它们融入结对做业中的

契约式设计,按照某种规定对一些数据等作出约定,若是超出约定,程序将再也不运行。
优势oop

  • 加入更多的条件检查,确保函数正常工做
  • 强制程序的前条件(pre-condition)、后条件(post-condition)、不变式(invariant)获得保证,从而使程序接口获得进一步的明确。

缺点post

  • 须要程序语言有断言机制

在编写的Core模块中,一开始对传入的参数进行合法性判断,须要调用该接口的主体保证数据的合法性。

8.计算模块部分单元测试展现

单元测试的代码以下

TEST_METHOD(TestMethod8)//-h b -t t -c

        {

            Core* core = new Core();

            char* result[100];

            char* words[] = { "abb","bccccccccccccccccccccc","cccccccccccccccccccccf","ctttt","cbt" };

            char* answer[] = { "bccccccccccccccccccccc","ctttt" };

            int answerlen = 2;

            int resultlen = core->gen_chain_char(words, 5, result, 'b', 't', false);

            Assert::AreEqual(resultlen, answerlen);

            int i = 0;

            for (i = 0; i < answerlen; i++)

            {

                string stranswer = answer[i];

                string strresult = result[i];

                Assert::AreEqual(stranswer, strresult);

            }

        }

这是一个测试约束首字母为'b',约束尾字母为't'的求字母最多的单词链的测试模块,在测试模块中words[]传入全部的单词,result存输出的结果,调用core计算模块中gen_chain_char接口,把返回到result中的结果和预先准备的answer中的答案进行比对。
在测试数据的构造上,主要是构造出有迷惑性的数据好比这一个数据要约束首位字母和字母最多,就构造了一个不符合首尾约束的字母更多的干扰的链,来测试程序可否计算正确。
在Core模块的正确性单元测试中一共设计了12个测试模块,包含了各类参数相结合的正确状况。
Core模块单元测试

单元测试覆盖率

Core模块单元测试覆盖率

9.计算模块部分异常处理说明

(1)"单词文本隐含单词环"异常

此异常应对当输入的单词可以构成单词环可是并无输入-r参数的状况。
单元测试样例以下

TEST_METHOD(ErrorTest1)//包含单词环可是没有-r参数

        {

            Core* core = new Core();

            char* result[100];

            char* words[] = { "apple","elephant","tea","alex","box","xob","cccccff","football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc" };

            char* answer[] = { "football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc","cccccff" };

            int answerlen = 3;

            try {

                int resultlen = core->gen_chain_char(words, 9, result, '\0', 'f', false);

            }

            catch (exception e) {

                Assert::AreEqual("单词文本隐含单词环", e.what());

            }

        }

其中 football -- llllllllllllllc --- cccccff 能造成单词环,可是 enable_loop 传入 false,应该抛出"单词文本隐含单词环"异常。

(2)"单词包含非法字符"异常

计算模块接口经过char* words[] 来传入所有单词,若是单词字符串中出现不是字母的状况,就应该抛出此异常。
单元测试样例以下

TEST_METHOD(ErrorTest2)//输入的单词中有非法字符,elephant 的字母l被空格代替

        {

            Core* core = new Core();

            char* result[100];

            char* words[] = { "apple","e ephant","tea","alex","box","xob","cccccff","football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc" };

            char* answer[] = { "football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc","cccccff" };

            int answerlen = 3;

            try {

                int resultlen = core->gen_chain_char(words, 9, result, '\0', 'f', false);

            }

            catch (exception e) {

                Assert::AreEqual("单词包含非法字符", e.what());

            }

        }

输入的单词中的第二个单词"e ephant"的第二个字符不是字母,应该抛出"单词包含非法字符"异常。

(3)"首尾字母约束不合法"异常

当传入的head 和 tail 参数既不是合法字母,也不是'\0'字符时抛出异常。
单元测试样例以下

TEST_METHOD(ErrorTest3)//首尾字母约束不合法,用 -h *

        {

            Core* core = new Core();

            char* result[100];

            char* words[] = { "apple","elephant","tea","alex","box","xob","cccccff","football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc" };

            char* answer[] = { "football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc","cccccff" };

            int answerlen = 3;

            try {

                int resultlen = core->gen_chain_char(words, 9, result, '*', '\0', false);

            }

            catch (exception e) {

                Assert::AreEqual("首尾字母约束不合法", e.what());

            }

        }

在调用gen_chain_char()时,head参数输入为'*',既不是字母也不是'\0',不合法,应当抛出"首尾字母约束不合法"异常。

(4)"有单词为空字符串"异常

当传入的words[]中有空字符串的时候,抛出此异常。
单元测试样例以下

TEST_METHOD(ErrorTest5)//有单词为空字符串 "

        {

            Core* core = new Core();

            char* result[100];

            char* words[] = { "apple","","tea","alex","box","xob","cccccff","football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc" };

            char* answer[] = { "football","lllllllllllllllllllllllllllllllllllllllllllllllllllllllllc","cccccff" };

            int answerlen = 3;

            try {

                int resultlen = core->gen_chain_char(words, 9, result, '\0', '\0', false);

            }

            catch (exception e) {

                Assert::AreEqual("有单词为空字符串", e.what());

            }

        }

传入的words[]中的第二个是 "" , 为空字符串,应当抛出"有单词为空字符串"异常。

Core模块抛出异常单元测试状况

Core模块异常状况测试

10.命令行模块的详细设计过程。

(1)首先经过main函数从命令行中获取参数的个数和具体的参数

int main(int argc, char* argv[])

(2)从第二个参数开始依次读取argv[]中的参数,与"-h","-t","-r","-w","-c"这五个参数进行比较,进行具体处理。

  • 若是是"-h"或者"-t"这两个约束首尾字母的参数,则直接读取argv[]中的下一个参数,根据规则,紧跟着的下一个参数应该是字母,若是不是则报错。
  • 若是是“-w"或者“-c”这两个参数,则直接读取argv[]中的下一个参数,根据规则,紧跟着的下一个参数应该是单词文本的路径,若是不是则报错。
  • 其中,“-w","-c"参数不能同时存在,"-h",”-t“参数能够同时存在,同一个参数不能出现两次,所以增长了五个布尔类型的变量进行是否重复的判断。

以判断”-h“参数为例,部分代码以下

for (i = 1; i < argc; i++)

            {

                parameter = argv[i];

                if (strcmp(parameter, "-h") == 0)

                {

                    if (if_head)

                    {

                        cout << "错误:-h参数重复" << endl;

                        exit(0);

                    }

                    if_head = true;

                    i++;

                    parameter = argv[i];

                    if (strlen(parameter) == 1 && isalpha(parameter[0]))

                    {

                        head_alpha = parameter[0];

                    }

                    else

                    {

                        cout << "错误:-h后没有字母" << endl;

                        exit(0);

                    }

                }

11.命令行模块与计算模块的对接

在main函数读入参数以后,直接进行命令行参数的处理,判断参数都正确以后,根据"-w" 和 "-c" 参数来分别调用Coe模块中的两个接口进行计算

if (if_word)

        {

            resultlen = core->gen_chain_word(words, wordslen, result, head_alpha, tail_alpha, if_roun);

        }

        else if (if_char)

        {

            resultlen = core->gen_chain_char(words, wordslen, result, head_alpha, tail_alpha, if_roun);

        }

12.描述结对的过程。

我和结对同窗基本上靠网络交流,经过微信来联系,我主要负责程序开发,结对同窗主要对程序进行测试,而后把问题反馈给我。

13.结对编程的优势和缺点

优势

  • 有人监督,不容易偷懒
  • 能在开发过程当中思惟互补,及时发现问题
  • 两我的各有所长,减小了一我的须要学习新知识的时间

缺点

  • 对“时空”要求较高,要约定时间地点一块儿编程。
  • 双方总会有分歧,要达成一致不免要一方妥协,略有不爽。
  • 代码风格不一样时,须要花时间理解。

    个人优势和缺点

    优势
  • 能静下心来多写代码
  • 按时完成任务
  • 推动任务的完成,比较主动
    缺点
  • 忘性大,常常写完了忘了上传
  • 代码风格有待改进
  • 对电脑系统的操做不熟悉

    结对同窗的优势和缺点

    优势
  • 作事细心,可以提醒我哪些文件没有上传,能发现细节上的错误。
  • 按时完成任务
  • 知识渊博,懂不少我不懂的知识和操做。
    缺点
  • 比较腼腆,不太爱说话。

    14.PSP表格 (实际花费时间)

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 1940 1410
·Estimate ·估计这个任务须要多少时间 1940 1410
Development 开发 1710 1210
·Analysis ·需求分析(包括学习新技术) 20 180
·Design Spec ·生成设计文档 20 20
·Design Review ·设计复审(和同事审核设计文档) 20 10
·Coding Standard ·代码规范(为目前的开发制定合适的规范) 20 10
·Design ·具体设计 30 30
·Coding ·具体编码 1000 600
·Code Review ·代码复审 300 180
·Test ·测试(自我测试,修改代码,提交修改) 300 180
Reporting 报告 230 220
·Test Report ·测试报告 200 200
·Size Measurement ·计算工做量 10 10
·Postmortem & Process Improvement Plan ·过后总结,并提出过程改进计划 20 10
合计 1960 1410
相关文章
相关标签/搜索