寒假作业(2/2)

|这个作业属于哪个课程|


:---😐:---😐:---:
|这个作业要求在哪里|
|这个作业的目标|阅读《构建之法》并提问、完成词频统计个人作业、撰写博客|
|作业正文|
|其他参考文献|csdn、老师的网站|

任务1

阅读《构建之法》并提问

1.选哪一种医生?

作为一个软件工程师,你觉得自己表现如何?有没有这样的体会:
看书的时候觉得“技止此耳”,开发项目的时候才觉得实际情况和书上讲的都有一些出入,一些重要的细节书上没有提。我们很多人是边看ASP.NET的书,边开发ASP.NET的项目,这相当于一边看医学书一边动手术……
如果你是病人,你希望你的医生是下面的哪一种呢?
a) 刚刚在书上看到你的病例,开刀的过程中非常认真严谨,时不时还要停下来翻书看看……
b) 富有创新意识,开刀时突然想到一个新技术、新的刀法,然后马上在你身上实验……
c) 已经处理过很多类似的病例,可以一边给你开刀,一边和护士聊天说昨天晚上的《非诚勿扰》花絮……
d) 此医生无正式文凭或正式医院的认证,但是号称有秘方,可治百病。
事实上,很多软件项目就是用a)或者b)这样的方法搞出来的。当然也有一些人走d)这条路。
讨论:
①你要选哪种类型的医生?
②医生、药剂师、律师和很多行业都有职业考试和职业证书,软件工程师需要有正式的职业证书才能上岗么?

假设我是病人,那显然我希望我的医生是c类,虽然软件工程师与医生的工作有着莫大的区别。
假设软件工程师的职业证书是依赖考试得到的,那我认为这样的职业证书的并没有什么太大意义,软件工程师与大部分行业有所不同的是它需要更多的实践和经验,这些依赖理论考试是没有什么可信度的。

2.我的看法

程序员小飞原计划三天完成某个任务,他说服了同事,坚持采用自己独特的实现方法。现在是第三天的下午,他马上就可以做完。但是在实现功能的过程中,他越来越意识到自已原来设计中的弱点,他应该采取另一个办法,才能程免后面集成阶段的额外工作。但是他如果现在就改弦更张。那就意味着公开承认自己的设计不好。并且会花费额外的时间。这样他的老板、同事也许会因此看不起他。如果他按部就班地按既定设计完成,最后整个团队还要花更多时间在后续集成上。但那就不是他个人的问题了。怎么办?

这也是我个人的疑问,同时也是时常出现在我身上的问题。之前在做团队比赛的时候时常会因为自己的独特的想法干扰到队友,甚至会因此导致比赛的失利。我认为我、小飞都应当认识到个人能力的局限性,个人的能力是有限的,即便想法再好,队友或是团队无法跟上思路或是特立独行的代码导致一次崩溃,也许就会因此颠覆整个项目。

3.关于代码量与成长

在书p65页的讨论中有提到当代码量与成长的关系。我有所疑问的是,倘若在项目上遇到自己不会学的已封装好的库,例如在sk-learn库中早已封装好各类机器学习的库,但只会调用库无法提高自己对于知识方面的进一步了解,但去彻底的了解源代码耗费的时间与得到的收获并不成正比,如何平衡这一方面的矛盾呢?

4.关于书中“分析麻痹”的疑惑

书p53页中阐述了过于细致的深究每个问题导致在项目上一开始就困难重重无法进行。那么一个项目想要正确的进行是应当只要求大方向正确接着慢慢去分小方向交接给不同的人去做吗?还是应当不求甚解,从头开始慢慢探索呢?

5.软件开发是一门工程,是一门艺术,还是一门手艺?

我认为软件开发必然是一门工程但同时也是一门艺术,它由众多人合作开发,必然涉及到了工程的知识,但它开发的方式也是美妙的,利用一行行代码展现出各种神奇的能力,谈为艺术也不为过。

任务二

GitHup项目地址 https://github.com/wugui1/PersonalProject-C

估计在各个板块的开发上耗费的时间与实际耗时

Personal Software Process Stages 预估耗时
计划
• 估计这个任务需要多少时间 3day
开发
• 需求分析 (包括学习新技术) 1day
• 生成设计文档 3h
• 设计复审 0.5h
• 代码规范 (为目前的开发制定合适的规范) 0.5h
• 具体设计 1h
• 具体编码 2h
• 代码复审 0.5h
• 测试(自我测试,修改代码,提交修改) 0.5h
报告 0.5h
• 测试报告 1h
• 计算工作量 1h
• 事后总结, 并提出过程改进计划 1h
合计 11.5h

解题思路与描述

我的大体思路是将输入的文件全转换为string类进行处理,返回string.length()即是字符数,接着为了输出前十个高频的单词,利用map进行去重和存储,为了二次排序,学习了map转换成vector的方法自定义比较类利用自带的sort函数进行排序。在输出行数的问题上,我利用遍历的方式处理。而最后在判断是否为单词的问题上我利用双指针的方式遍历一遍输入的string类,第一个指针指向查询到的第一个字母,第二个指针沿着第一个指针进行查询。

代码规范的链接 https://github.com/wugui1/PersonalProject-C/blob/main/031801133/codestyle.md

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

接口部分如下,传入的皆为文本被转换后的string

int countChar(string input); //计算字符
int countWord(string input);  //计算单词数
int countR(string input);  //计算行数
void showWord(string input);  //输出前十个单词

 

对于读取文件将其导入string的功能我单独放在了main函数
ifstream in("input.txt", ios::in);
  istreambuf_iterator<char> beg(in), end;
  string input(beg, end);
  cout << input<<endl;

 

统计字符数

直接返回string的length即可

return input.length();

统计单词数

在遍历一遍输入时利用两个指针i,j进行遍历,假设碰到的第一个为字母,判断接下来三个是否依旧是字母

for (; j < i + 4; j++) {
  if (!isword(input[j])) {
    flag = 0;
    break;
  }
}

如果是,则判断为单词,将其放入map中,并将指针更新

if (flag) {
  while (notsp(input[j])){
    j++;
  }
  if (m[input.substr(i, j - i)] == 0) {
    m[input.substr(i, j - i)]++;
    sum++;
  }
  else m[input.substr(i, j - i)]++;
  i = j + 1;
  j = i;
  }
  else {
    i = j + 1;
    j = i;
  }
}

否则将查询单词末尾的指针不断递增碰到空白字符时跳过并将指针更新

统计行数

遍历一遍输入,判断有几个换行符,若有相邻的换行符或是空白字符便跳过到下一个不是换行符的字母,并判断最后一个字符是否不是换行符,若不是另加一

for (; i < input.length(); i++) {
  if ((input[i] == 13 || input[i] == 10)) {
    sum++;
    while (isWhite(input[i]))
      i++;
    }
  }

统计词频

利用map进行存储,为了排序再将map转换成vector进行自定义排序
自定义比较函数

bool cmp(pair<string, int> a, pair<string, int> b) {
  if (a.second == b.second)	return a.first < b.first;
  return a.second > b.second;
}

map转换成vector进行自定义排序

for (map<string, int>::iterator it = m.begin(); it != m.end(); it++) {
  vec.push_back(pair<string, int>(it->first, it->second));
}
sort(vec.begin(), vec.end(), cmp);

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

在进行计算单词总数的时候一开始利用两个循环进行嵌套,第一遍遍历字母头,第二遍遍历字母头所在的末尾,所用的时间复杂度为O(n^2),后来利用两个指针进行遍历下降到了O(n)的复杂度。

计算模块部分单元测试展示

50000行file123在VS上进行测试
测试代码如下

TEST_METHOD(TestMethod1)
{
  ofstream OutFile("Unitest.txt");
for (int i = 0; i < 50000; i++) {
OutFile << "file123" << endl;
}
string way = "Unitest.txt";
string test = getInput(way);
int ans_char = 400000;
int ecp_char = countChar(test);
Assert::AreEqual(ecp_char, ans_char);
int ans_word = 50000;
int ecp_word = countWord(test);
Assert::AreEqual(ecp_word, ans_word);
int ans_R = 50000;
Assert::AreEqual(countR(test), ans_R);
}

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

文件无法打开时将会报错。

在程序的各个模块上实际花费的时间

Personal Software Process Stages 实际耗时
计划
• 估计这个任务需要多少时间 3day
开发
• 需求分析 (包括学习新技术) 1day
• 生成设计文档 2h
• 设计复审 1h
• 代码规范 (为目前的开发制定合适的规范) 0.5h
• 具体设计 1h
• 具体编码 4h
• 代码复审 0.5h
• 测试(自我测试,修改代码,提交修改) 0.5h
报告 0.5h
• 测试报告 3h
• 计算工作量 1h
• 事后总结, 并提出过程改进计划 1h
合计 15h

心路历程与收获

在开始收到任务的时候就开始准备学习,不过发现作业慢慢感觉能做完的时候后面就一直开始摸鱼了....今后应当一口气全部做完不能一直拖着。
而我最大的收获便是GitHub上的学习,之前在GitHub上学习别人数据处理的代码的时候一直不太能明白这个平台到底是用来做什么的,只能下载下来看,没想到它的功能如此的强大。以及能感觉到在团队写作的时候这个平台的功能的用处,下次团队协作的时候应当更深入的学习GitHub。

posted @ 2021-03-04 18:23  _Hans  阅读(100)  评论(4编辑  收藏  举报