非不认真,非不努力,奈什么时候间所剩无几,未能提交最完美的做业git
https://github.com/awfsgdf/coyg
虽然咱们GitHub项目的tag提交时间很晚,但实际上咱们很早就开始写代码了,只是没有注意到做业要求github
Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|
计划 | 60 | 60 |
· 估计这个任务须要多少时间 | 60 | 60 |
开发 | 1400 | 1810 |
· 需求分析 (包括学习新技术) | 120 | 60 |
· 生成设计文档 | 120 | 30 |
· 设计复审 (和同事审核设计文档) | 60 | 30 |
· 代码规范 (为目前的开发制定合适的规范) | 20 | 10 |
· 具体设计 | 120 | 240 |
· 具体编码 | 720 | 1080 |
· 代码复审 | 120 | 60 |
· 测试(自我测试,修改代码,提交修改) | 120 | 300 |
报告 | 180 | 180 |
· 测试报告 | 60 | 60 |
· 计算工做量 | 60 | 60 |
· 过后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 1640 | 2050 |
咱们应用了信息隐藏:设置类的private参数;接口设计:尽可能知足能够在任何环境调用;松耦合:因为GUI没有作出来因此没有实现。编程
先把以a-z开头的单词分别存在26个向量中,把以a-z结尾的单词分别存在26个向量中,以这52个向量来保存图的信息,而后根据图的信息和输入的参数计算出能够做为遍历开始的点的集合,而后依次以这个集合里的点做为DFS的起点,进行深度优先搜索,找出最长单词链。其中有些细节这里再也不详述,代码注释写的比较清楚。数组
在没有环的图中,因为图的结构比较简单,我认为爆搜所有路径是一种奢侈,因而采用了相似剪枝的方法,省去了大量确定得不到最长路径的遍历,运行时间比较短。在有环的途中,无奈本人学艺不精,找不到更高效的方法,只能DFS爆搜,可是我发现个人爆搜过程严重超时,通过查找资料和分析代码,我发现个人DFS的问题在于它传入的无用的参数太多了,因而我把一些变量设置为类变量,再也不做为参数传入,只是在调用寻找最长链的函数中声明一个类对象,这样修改以后跑同一份代码的时间居然缩短为原来的十分之一(从十分钟缩短到到一分钟)。由此我了解到,函数传入的参数过多确实会严重影响运行效率。下图为改进以后的DFS函数爆搜100个点带环图最长单词链的性能分析图。函数
优势是在编译的时候就能够检查程序的正确性,并且经过这种方法保证了程序的正确性;缺点是无法自由地控制契约是否生效,并且对于存在大量输入输出的函数会拖慢运行速度。
咱们应用的方法是对每一个模块都作正确性测试,以提高整个工程的正确性。oop
单元测试获得的测试覆盖率截图以下所示
(注:此部分覆盖截图和测试样例代码由个人队友提供)
性能
char* input[4] = { (char*)"END", (char*)"OF", (char*)"THE", (char*)"WORLD" }; char* result[4] = { 0 }; gen_chain_word(input, 4, result, 0, 0, false); char* input1[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox",(char*) "Dog", (char*)"Moon", (char*)"Leaf",(char*)"Trick",(char*) "Pseudopseudohypoparathyroidism" }; char* result1[11] = { 0 }; gen_chain_word(input1, 11, result1, 0, 0, false); char* input2[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result2[11] = { 0 }; gen_chain_char(input2, 11, result2, 0, 0, false); char* input3[5] = { (char*)"Element", (char*)"heaven", (char*)"Table",(char*) "Teach", (char*)"Talk" }; char* result3[5] = { 0 }; gen_chain_word(input3, 5, result3, 0, 0, true); char* input4[5] = { (char*)"Element", (char*)"heaven", (char*)"Table",(char*) "Teach", (char*)"Talk" }; char* result4[5] = { 0 }; gen_chain_char(input4, 5, result4, 0, 0, true); char* input5[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result5[11] = { 0 }; gen_chain_word(input5, 11, result5, 'a', 0, false); char* input6[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result6[11] = { 0 }; int len = gen_chain_char(input6, 11, result6, 'a', 0, false); char* input7[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result7[11] = { 0 }; gen_chain_word(input7, 11, result7, 0, 'n', false); char* input8[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result8[11] = { 0 }; gen_chain_char(input8, 11, result8, 0, 'n', false); char* input9[5] = { (char*)"Element", (char*)"heaven", (char*)"Table",(char*) "Teach", (char*)"Talk" }; char* result9[5] = { 0 }; gen_chain_word(input9, 5, result9, 't', 0, true); char* input10[5] = { (char*)"Element", (char*)"heaven", (char*)"Table",(char*) "Teach", (char*)"Talk" }; char* result10[5] = { 0 }; gen_chain_char(input10, 5, result10, 't', 0, true); char* input11[5] = { (char*)"Element", (char*)"heaven", (char*)"Table",(char*) "Teach", (char*)"Talk" }; char* result11[5] = { 0 }; gen_chain_word(input11, 5, result11, 0, 'n', true); char* input12[5] = { (char*)"Element", (char*)"heaven", (char*)"Table",(char*) "Teach", (char*)"Talk" }; char* result12[5] = { 0 }; gen_chain_word(input12, 5, result12, 0, 'n', true); char* input13[5] = { (char*)"aa", (char*)"aaa", (char*)"aaaa", (char*)"aaaaa", (char*)"a" }; char* result13[5] = { 0 }; gen_chain_word(input13, 5, result13, 0, 0, true);*/ char* input14[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result14[11] = { 0 }; gen_chain_word(input14, 11, result14, 'a', 'k', false); char* input15[11] = { (char*)"Algebra", (char*)"Apple", (char*)"Zoo", (char*)"Elephant", (char*)"Under", (char*)"Fox", (char*)"Dog",(char*) "Moon",(char*) "Leaf",(char*)"Trick", (char*)"Pseudopseudohypoparathyroidism" }; char* result15[11] = { 0 }; gen_chain_word(input15, 11, result15, 's', 's', false);
异常处理函数 | 功能 | 异常样例 |
---|---|---|
void check_h_and_t(char head, char tail, bool have_head, bool have_tail); | 检查是否存在head开头和tail结尾的单词 | 输入的单词列表为{"hello", "world" , "yes"},而命令行窗口输入的参数包含-h a -t b |
void check_file(); | 检查输入单词文件的路径是否正确 | 输入的文件路径错误或者没有路径指定文件 |
void check_loop(bool enable_loop, int size); | 检查输入的单词列表有无环是否和-r参数匹配 | 输入的单词列表为{"hello", "olleh", "yes"},而命令行窗口输入的参数不包含-r |
void check_null(char *word); | 检查传入的char *word[]里是否有空指针 | 输入的单词列表char *[]在下标0到下标len-1这些元素之间有空指针 |
void check_char(int i); | 检查传入的单词列表里是否都是英文单词 | 输入的单词列表为{"h3llo","w0rld", "yes"} |
void check_void(int len); | 输入的单词列表的单词数量是否小于2 | 输入的单词列表为{"hello"} |
void check_2(); | 检查搜索到的单词链的单词数量是否小于2 | 搜索到的单词链为{"hello"} |
void check_same(); | 检查输入的单词列表中是否有重复的单词 | 输入的单词列表为{"hello", "hello"} |
int find_arg(int argc, char *argv[], arg &w, arg &c, arg &h, arg &t, arg &r, char &head, char &tail); | 检查传入的参数组合是否出错,若是出错,以int形式返回错误的类型以便分状况报错 | 输入的参数不包含-w且不包含-c,返回int类型数据4 |
参数的定义和做业要求一致,当参数输入不符合逻辑时会报相应错误,例如-w和-c同时出现,-w和-c同时未出现,-h参数错误,-t参数错误,源文件不存在等等。单元测试
如下是命令行运行.exe文件的截图。
学习
结对不是一个容易的过程,因为种种缘由,我和队友没有很长的时间能够结对编程,所以程序的代码部分是我一人编写,只是在最后两天编写测试用例、对接GUI的时候咱们一块儿结对编程了一段时间,可是因为除了编写代码以外的后续工做开展的太晚致使咱们最终提交的项目并不完美,可是我已经对本身满意。在写此次做业的过程当中,我既体会到了单人爆肝的辛苦,也体会到告终对编程的乐趣,能够说作此次做业的过程是一种历练。
测试
结对编程的优势:
1)能够互相督促,不会纵容某一方拖延
2)一边写代码一边有人监督不易出错
3)两我的能够常常交流,分享知识。
结对编程的缺点:
1)可能仍是会让人不太适应吧。
个人优势:
1)比较认真
2)比较刻苦
3)比较爱学习
个人缺点:
1)没有给予队友足够帮助
个人结对对象优势:
1)比较刻苦
2)作事比较有条例
3)求知欲比较强
个人结对对象缺点:
比较不守时,没有按时完成任务。
表格见上文。