算法第一章作业

算法第一章作业

一、编码规范

本学期我的编码满足Google开源代码规范

https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/

下面列出一些比较常用并且重要的规范

函数

参数顺序

总述

函数的参数顺序为: 输入参数在先, 后跟输出参数.

编写简短函数

总述

我们倾向于编写简短, 凝练的函数.

说明

我们承认长函数有时是合理的, 因此并不硬性限制函数的长度. 如果函数超过 40 行, 可以思索一下能不能在不影响程序结构的前提下对其进行分割.

即使一个长函数现在工作的非常好, 一旦有人对其修改, 有可能出现新的问题, 甚至导致难以发现的 bug. 使函数尽量简短, 以便于他人阅读和修改代码.

在处理代码时, 你可能会发现复杂的长函数. 不要害怕修改现有代码: 如果证实这些代码使用 / 调试起来很困难, 或者你只需要使用其中的一小段代码, 考虑将其分割为更加简短并易于管理的若干函数.

注释

注释虽然写起来很痛苦, 但对保证代码可读性至关重要. 下面的规则描述了如何注释以及在哪儿注释. 当然也要记住: 注释固然很重要, 但最好的代码应当本身就是文档. 有意义的类型名和变量名, 要远胜过要用注释解释的含糊不清的名字.

注释风格

总述

使用 ///* */, 统一就好.

说明

///* */ 都可以; 但 // 常用. 要在如何注释及注释风格上确保统一.

函数注释

总述

函数声明处的注释描述函数功能; 定义处的注释描述函数实现.

说明

函数声明

基本上每个函数声明处前都应当加上注释, 描述函数的功能和用途. 只有在函数的功能简单而明显时才能省略这些注释(例如, 简单的取值和设值函数). 注释使用叙述式 (“Opens the file”) 而非指令式 (“Open the file”); 注释只是为了描述函数, 而不是命令函数做什么. 通常, 注释不会描述函数如何工作. 那是函数定义部分的事情.

函数声明处注释的内容:

  • 函数的输入输出.

  • 对类成员函数而言: 函数调用期间对象是否需要保持引用参数, 是否会释放这些参数.

  • 函数是否分配了必须由调用者释放的空间.

  • 参数是否可以为空指针.

  • 是否存在函数使用上的性能隐患.

  • 如果函数是可重入的, 其同步前提是什么?

举例如下:

 // Returns an iterator for this table.  It is the client's
 // responsibility to delete the iterator when it is done with it,
 // and it must not use the iterator once the GargantuanTable object
 // on which the iterator was created has been deleted.
 //
 // The iterator is initially positioned at the beginning of the table.
 //
 // This method is equivalent to:
 //   Iterator* iter = table->NewIterator();
 //   iter->Seek("");
 //   return iter;
 // If you are going to immediately seek to another place in the
 // returned iterator, it will be faster to use NewIterator()
 // and avoid the extra seek.
 Iterator* GetIterator() const;

但也要避免罗罗嗦嗦, 或者对显而易见的内容进行说明. 下面的注释就没有必要加上 “否则返回 false”, 因为已经暗含其中了:

 // Returns true if the table cannot hold any more entries.
 bool IsTableFull();

注释函数重载时, 注释的重点应该是函数中被重载的部分, 而不是简单的重复被重载的函数的注释. 多数情况下, 函数重载不需要额外的文档, 因此也没有必要加上注释.

注释构造/析构函数时, 切记读代码的人知道构造/析构函数的功能, 所以 “销毁这一对象” 这样的注释是没有意义的. 你应当注明的是注明构造函数对参数做了什么 (例如, 是否取得指针所有权) 以及析构函数清理了什么. 如果都是些无关紧要的内容, 直接省掉注释. 析构函数前没有注释是很正常的.

函数定义

如果函数的实现过程中用到了很巧妙的方式, 那么在函数定义处应当加上解释性的注释. 例如, 你所使用的编程技巧, 实现的大致步骤, 或解释如此实现的理由. 举个例子, 你可以说明为什么函数的前半部分要加锁而后半部分不需要.

不要.h 文件或其他地方的函数声明处直接复制注释. 简要重述函数功能是可以的, 但注释重点要放在如何实现上.

变量注释

总述

通常变量名本身足以很好说明变量用途. 某些情况下, 也需要额外的注释说明.

说明

类数据成员

每个类数据成员 (也叫实例变量或成员变量) 都应该用注释说明用途. 如果有非变量的参数(例如特殊值, 数据成员之间的关系, 生命周期等)不能够用类型与变量名明确表达, 则应当加上注释. 然而, 如果变量类型与变量名已经足以描述一个变量, 那么就不再需要加上注释.

特别地, 如果变量可以接受 NULL-1 等警戒值, 须加以说明. 比如:

 private:
  // Used to bounds-check table accesses. -1 means
  // that we don't yet know how many entries the table has.
  int num_total_entries_;

全局变量

和数据成员一样, 所有全局变量也要注释说明含义及用途, 以及作为全局变量的原因. 比如:

 // The total number of tests cases that we run through in this regression test.
 const int kNumTestCases = 6;

二、数学之美与算法

算法的含义

广义上的算法:只要写程序就是算法,把大象装进冰箱,分三步,就是一个简单的算法。

狭义的算法:分治、动态规划、排序、数据结构等复杂的完成任务的流程.

严格的算法定义:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。

数学之美 PageRank章节

在1988年以前,用户在网络上使用搜索引擎进行搜素时,对于搜索到的结果,是没有重要性程度的排序的,通常是一些不相关的信息,用户通常需要翻找好几页,才能找到自己需要的内容。于是,给搜索结果排序,成为了搜索引擎公司的一项至关重要的任务,因为这个问题,很大程度上决定了搜索引擎的质量。

针对这个问题,Google找到了答案。PageRank的算法的核心思想是:在互联网上,如果一个网页被其他很多网页所链接,说明它受到普遍的承认和信赖,那么它的排名就高。类似于,网页和网页之间相互投票,谁的票数高,就证明谁的权威性更大。

接着,他们又通过数学证明,证明了如何选取给个网页打分的初始值,使用稀疏矩阵算法,简化了计算量。这一革命性的技术,可以说在某种程度上,造就了Google的成功。这足以体现算法在软件开发中的重要性。



posted @ 2020-09-15 23:40  幼儿算数  阅读(157)  评论(0编辑  收藏  举报