Skip to content

Commit 9bf72ac

Browse files
committed
fix typo
1 parent 7c4c4d6 commit 9bf72ac

File tree

5 files changed

+17
-14
lines changed

5 files changed

+17
-14
lines changed

1.介绍/1.1.目标/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
## 1.1.目标
33

4-
* 回顾计算机科学的思想, 提高编程和解决问题的 能力
4+
* 回顾计算机科学的思想, 提高编程和解决问题的能力
55
* 理解抽象化以及它在解决问题过程中发挥的作用
66
* 理解和实现抽象数据类型的概念
77
* 回顾 Python 编程语言

1.介绍/1.5.为什么要学习数据结构和抽象数据类型/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
为了管理问题的复杂性和解决问题的过程,计算机科学家使用抽象使他们能够专注于 “大局” 而不会迷失在细节中。通过创建问题域的模型,我们能够利用更好和更有效的问题解决过程。这些模型允许我们以更加一致的方式描述我们的算法将要处理的数据。
44

5-
之前,我们将过程抽象称为隐藏特定函数的细节的过程,以允许用户或客户端在高层查看它。我们现在将注意力转向类似的思想,即数据抽象的思想。`抽象数据类型`(有时缩写为 ADT )是对我们如何查看数据和允许的操作的逻辑描述,而不y用考虑如何实现它们。这意味着我们只关心数据表示什么,而不关心它最终将如何构造。通过提供这种级别的抽象,我们围绕数据创建一个封装。通过封装实现细节,我们将它们从用户的视图中隐藏。这称为信息隐藏。
5+
之前,我们将过程抽象称为隐藏特定函数的细节的过程,以允许用户或客户端在高层查看它。我们现在将注意力转向类似的思想,即数据抽象的思想。`抽象数据类型`(有时缩写为 ADT )是对我们如何查看数据和允许的操作的逻辑描述,而不用考虑如何实现它们。这意味着我们只关心数据表示什么,而不关心它最终将如何构造。通过提供这种级别的抽象,我们围绕数据创建一个封装。通过封装实现细节,我们将它们从用户的视图中隐藏。这称为信息隐藏。
66

7-
Figure 2 展示了抽象数据类型是什么以及如何操作。用户与接口交互,使用抽象数据类型指定的操作。抽象数据类型是用户与之交互的 shell。实现是隐藏在更深的底层。用户不关心实现的细节。
7+
Figure 2 展示了抽象数据类型是什么以及如何操作。用户与接口交互,使用抽象数据类型指定的操作。抽象数据类型是用户与之交互的 shell。实现隐藏在更深的底层。用户不关心实现的细节。
88
![1.5.为什么要学习数据结构和抽象数据类型.figure2](assets/1.5.%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%AD%A6%E4%B9%A0%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E6%8A%BD%E8%B1%A1%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.figure2.png)
9+
10+
911
*Figure 2*
1012

1113
抽象数据类型(通常称为数据结构)的实现将要求我们使用一些程序构建和原始数据类型的集合来提供数据的物理视图。 正如我们前面讨论的,这两个视角的分离将允许我们将问题定义复杂的数据模型,而不给出关于模型如何实际构建的细节。 这提供了独立于实现的数据视图。由于通常有许多不同的方法来实现抽象数据类型,所以这种实现独立性允许程序员在不改变数据的用户与其交互的方式的情况下切换实现的细节。 用户可以继续专注于解决问题的过程。

1.介绍/1.6.为什么要学习算法/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 1.6.为什么要学习算法
22

3-
计算机科学家通过经验学习。我们通过看别人解决问题和自己解决问题来学习。接触不同的问题解决技术,看不同的算法设计有助于我们承担下一个具有挑战性的问题。通过思考许多不同的算法,我们可以开始开发模式识别,以便下一次出现类似的问题时,我们能够更好地解决它。
3+
计算机科学家经常通过经验学习。我们通过看别人解决问题和自己解决问题来学习。接触不同的问题解决技术,看不同的算法设计有助于我们承担下一个具有挑战性的问题。通过思考许多不同的算法,我们可以开始开发模式识别,以便下一次出现类似的问题时,我们能够更好地解决它。
44

55
算法通常彼此完全不同。考虑前面看到的 `sqrt` 的例子。完全可能的是,存在许多不同的方式来实现细节以计算平方根函数。一种算法可以使用比另一种更少的资源。一个算法可能需要 10 倍的时间来返回结果。我们想要一些方法来比较这两个解决方案。即使他们都工作,一个可能比另一个“更好”。我们建议使用一个更高效,或者一个只是工作更快或使用更少的内存的算法。当我们研究算法时,我们可以学习分析技术,允许我们仅仅根据自己的特征而不是用于实现它们的程序或计算机的特征来比较和对比解决方案。
66

2.算法分析/2.2.什么是算法分析/README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@ print(foo(10))
3030
````
3131
*ActiveCode 2*
3232

33-
先前我们提出一个问题是哪个函数更好,答案取决于你的标准。如果你关注可读性,函数 sumOfN 肯定比 foo 好。事实上,你可能已经在你介绍编程的课程中看到过很多例子,他们的目标之一就是帮助你编写易于阅读和理解的程序。在本课程中,我们对如何表示算法感兴趣(当然我们希望你继续努力编写可读的,易于理解的代码)。
33+
先前我们提出一个问题是哪个函数更好,答案取决于你的标准。如果你关注可读性,函数 sumOfN 肯定比 foo 好。事实上,你可能已经在介绍编程的课程中看到过很多例子,他们的目标之一就是帮助你编写易于阅读和理解的程序。在本课程中,我们对如何表示算法感兴趣(当然我们希望你继续努力编写可读的,易于理解的代码)。
3434

35-
算法分析涉及基于每个算法使用的计算资源量来比较算法。我们比较两个算法,说一个比另一个算法好的原因在于它在使用资源方面更有效率,或者仅仅使用的资源更少。从这个角度来看,上面两个函数看起来很相似。它们都使用基本相同的算法来求解问题。在这点上,更重要的是我们如何考虑真正意义上的计算资源。有两个方法,一种是考虑算法所需的空间或者内存。所需的空间通常由问题本身决定。但是,算法会有一些特殊的空间需求,我们可以细细观察解释这些变动。
35+
算法分析涉及基于每个算法使用的计算资源量来比较算法。我们比较两个算法,说一个比另一个算法好的原因在于它在使用资源方面更有效率,或者仅仅使用的资源更少。从这个角度来看,上面两个函数看起来很相似。它们都使用基本相同的算法来求解问题。在这点上,更重要的是我们如何考虑真正意义上的计算资源。有两种方法,一种是考虑算法所需的空间或者内存。所需的空间通常由问题本身决定。但是,算法会有一些特殊的空间需求,我们可以细细观察解释这些变动。
3636

3737
作为空间需求的一种替代方法,我们可以基于时间来分析算法。这种度量有时被称为算法的‘执行时间’或’运行时间‘。我们可以通过基准分析来测量函数 SumOfN 的执行时间。这意味着我们将记录程序计算所需的实际时间。在 Python 中,我们可以通过记录相对于系统的开始时间和结束时间来对函数进行基准测试。在时间模块中有一个时间函数,它将返回系统时钟时间(以秒为单位)。通过在开始和结束的时候调用时间函数,然后计算差异,就可以得到一个精确地秒数(大多数情况下)。
3838

39-
#### Listing 1
4039

4140
```` python
4241
import time
@@ -52,8 +51,10 @@ def sumOfN2(n):
5251

5352
return theSum,end-start
5453
````
54+
*Listing 1*
5555

56-
Listing 1 嵌入了时间函数,函数返回一个包含结果和消耗时间的数组。如果我们 执行这个函数 5 次,每次计算前 10,000 个整数的和,将得到一下结果:
56+
57+
Listing 1 嵌入了时间函数,函数返回一个包含结果和消耗时间的数组。如果我们执行这个函数 5 次,每次计算前 10,000 个整数的和,将得到如下结果:
5758

5859
````
5960
>>>for i in range(5):
@@ -102,7 +103,7 @@ print(sumOfN3(10))
102103
````
103104
*ActiveCode 3*
104105

105-
如果我们对 sumOfN3 做同样的基准测试,使用 5 个不同的 n(10,000, 100,000, 1,000,000, 100,000,000), 我们得到如下结果
106+
如果我们对 sumOfN3 做同样的基准测试,使用 5 个不同的 n `(10,000, 100,000, 1,000,000, 100,000,000)`, 我们得到如下结果
106107

107108
```` python
108109
Sum is 50005000 required 0.00000095 seconds
@@ -112,9 +113,9 @@ Sum is 50000005000000 required 0.00000095 seconds
112113
Sum is 5000000050000000 required 0.00000119 seconds
113114
````
114115

115-
有两点关注下,首先上面记录的时间比上面任何例子都短, 另外他们的时间和 n 无关, 看来 sumOfN3 几乎不受 n 的影响。
116+
有两点关注下,首先上面记录的时间比上面任何例子都短,另外他们的时间和 n 无关,看来 sumOfN3 几乎不受 n 的影响。
116117

117-
但是这个基准测试告诉我们什么?我们可以直观的看到用迭代的方案在做更多的工作,因为一些步骤重复。这可能是它需要更长时间的原因。此外,迭代所需时间随着 n 递增。还有个问题,如果我们在不同计算机上或者使用不用的编程语言运行这个函数,我们也可能得到不同的结果。如果用老计算机,可能需要更长时间才能执行完 sumOfN3。
118+
但是这个基准测试告诉我们什么?我们可以直观的看到用迭代的方案需要做更多的工作,因为一些步骤重复。这可能是它需要更长时间的原因。此外,迭代所需时间随着 n 递增。还有个问题,如果我们在不同计算机上或者使用不用的编程语言运行这个函数,我们也可能得到不同的结果。如果用老计算机,可能需要更长时间才能执行完 sumOfN3。
118119

119120

120121
我们需要一个更好的方法来表征这些算法的执行时间。基准测试计算的是执行的实际时间。它并不真正提供给我们一个有用的测量,因为它取决于特定的机器,程序,时间,编译器和编程语言。 相反,我们希望具有独立于所使用的程序或计算机的特性。不过基准度量将有助于单独判断算法,并且可以用于在方案之间比较算法。

2.算法分析/2.3.大O符号/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
## 2.3.大O符号
2-
当我们试图通过执行时间来表征算法的效率时,并且独立于任何特定程序或计算机,重要的是量化算法需要的操作或者步骤的数量。选择适当的基本计算单位是个复杂的问题,并且将取决于如何实现算法。对于先前的求和算法,一个比较好的基本计算单位是对执行语句进行计数。在 sumOfN 中,赋值语句的计数为 1 (\(theSum = 0\)) 加上 n 的值(我们执行 \(theSum=theSum+i\) 的次数)。我们通过函数 T 表示 \(T(n)=1 + n\)。参数 n 通常称为‘问题的规模’,我们称作 ‘T(n) 是解决问题大小为 n 所花费的时间,即 1+n 步长’。在上面的求和函数中,使用 n 来表示问题大小是有意义的。我们可以说,100,000 个整数和比 1000 个问题规模大。因此,所需时间也更长。我们的目标是表示出算法的执行时间是如何相对问题规模大小而改变的。
2+
当我们试图通过执行时间来表征算法的效率时,并且独立于任何特定程序或计算机,重要的是量化算法需要的操作或者步骤的数量。选择适当的基本计算单位是个复杂的问题,并且将取决于如何实现算法。对于先前的求和算法,一个比较好的基本计算单位是对执行语句进行计数。在 sumOfN 中,赋值语句的计数为 1 `(theSum = 0)` 加上 n 的值(我们执行 `theSum=theSum+i` 的次数)。我们通过函数 T 表示 `T(n)=1 + n`。参数 n 通常称为‘问题的规模’,我们称作 ‘T(n) 是解决问题大小为 n 所花费的时间,即 1+n 步长’。在上面的求和函数中,使用 n 来表示问题大小是有意义的。我们可以说,100,000 个整数和比 1000 个问题规模大。因此,所需时间也更长。我们的目标是表示出算法的执行时间是如何相对问题规模大小而改变的。
33

4-
计算机科学家更喜欢将这种分析技术进一步。事实证明,操作步骤数量不如确定 \(T(n)\) 最主要的部分来的重要。换句话说,当问题规模变大时, \(T(n)\) 函数某些部分的分量会超过其他部分。函数的数量级表示了随着 n 的值增加而增加最快的那些部分。数量级通常称为大O符号,并写为 \(O(f(n))\)。它表示对计算中的实际步数的近似。函数 \(f(n)\) 提供了 \(T(n)\) 最主要部分的表示方法。
4+
计算机科学家更喜欢将这种分析技术进一步扩展。事实证明,操作步骤数量不如确定 T(n) 最主要的部分来的重要。换句话说,当问题规模变大时,T(n) 函数某些部分的分量会超过其他部分。函数的数量级表示了随着 n 的值增加而增加最快的那些部分。数量级通常称为大O符号,写为 `O(f(n))`。它表示对计算中的实际步数的近似。函数 f(n) 提供了 T(n) 最主要部分的表示方法。
55

6-
在上述示例中,\(T(n)=1+n\)。当 n 变大时,常熟 1 对于最终结果变得越来越不重要。如果我们找的是 \(T(n)\) 的近似值,我们可以删除 1, 运行时间是\(O(n)\)。要注意,1 对于 \(T(n)\) 肯定是重要的。但是当 n 变大时,如果没有它,我们的近似也是准确的。
6+
在上述示例中,`T(n)=1+n`。当 n 变大时,常熟 1 对于最终结果变得越来越不重要。如果我们找的是 \(T(n)\) 的近似值,我们可以删除 1, 运行时间是\(O(n)\)。要注意,1 对于 \(T(n)\) 肯定是重要的。但是当 n 变大时,如果没有它,我们的近似也是准确的。
77

88
另外一个示例,假设对于一些算法,确定的步数是 T(n)=5n^2 +27n+1005。当 n 很小时, 例如 1 或 2 ,常数 1005 似乎是函数的主要部分。然而,随着 n 变大,\(n^2\) 这项变得越来越重要。事实上,当 n 真的很大时,其他两项在它们确定最终结果中所起的作用变得不重要。当 n 变大时,为了近似\(T(n)\),我们可以忽略其他项,只关注 \(5n^2 \)。系数 5 也变得不重要。我们说,\(T(n)\) 具有的数量级为 f(n)=n^2。 或者 O( n^2 ) 。
99

0 commit comments

Comments
 (0)