目录
- 说明
- 一.第一章
- 1.1. 问题求解的计算之道
- 1.2. 图灵机的计算模型
- 1.3. 算法和计算复杂性
- 1.4. 突破计算极限
- 1.5. 什么是抽象什么是实现
- 1.6. 为什么研究数据结构
- 1.7. 书籍补充
- 二.第二章
- 2.1. 什么是算法分析
- 2.2. 大O表示法
- 2.3. 变位词的判断问题
- 2.4. python数据类型的性能
- 2.5. 如何做OJ
- 2.6. 列表
- 2.7. 字典
- 三.第二周OJ
- 题目1.
- 题目2.
- 题目3.
- 四. 总结
说明
在结束MOOC的数据结构与算法python版的课,看了python 数据结构与算法分析(第二版)后,深感内容详实,故记录有用的内容进行总结。发布的代码以课程上的为主,我笔记本上跑过都是通的。课后作业的代码太多,参考了不少,不过即使是我想了很久的,也并不是全部AC。就这样吧(躺)。虽然计算机是人类造的但还是有不少未解之谜。
一.第一章
这一章是入门知识。书上关于面向对象编程是我不擅长的,因此总结tips。
1.1. 问题求解的计算之道
- 问题:未知事物
a. What
b. Why
c. How - 问题的解决之道(过程)
从未知到已知 - 通过该过程得到的解决方案
- 工具【能行可计算】
- 数学
- 为了解决数学本身的可
检验性问题,大数学家希尔伯特提出“能
否找到一种基于有穷观点的能行方法,来
判定任何一个数学命题的真假” - 基于有穷观点的能行方法:
a. 由有限数量的明确有限指令构成;
指令执行在有限步骤后终止;
b. 指令每次执行都总能得到唯一结果;
原则上可以由人单独采用纸笔完成,而不依靠其
它辅助;
c. 每条指令可以机械地被精确执行,而不需要智慧
和灵感
1.2. 图灵机的计算模型
- 图灵机的基本概念
- 控制规则是五元组
- 必须有一条规则是S0开头的
- 图灵机可以永不停机
1.3. 算法和计算复杂性
- What,Why和How可以通过有限能行的方法的计算模型解决的,都算“可计算”的模型
- 基于有穷观点的能行方法的可计算概念:
能在有限资源内解决否 - 但是人类的资源非常有限,因此考虑可行性
- 计算复杂性理论研究问题的本质,将各种问题按
照其难易程度分类,研究各类问题的难度级别,
并不关心解决问题的具体方案 - 而算法则研究问题在不同现实资源约束情况下的
不同解决方案,致力于找到效率最高的方案 - 不可计算问题:比如停机问题
1.4. 突破计算极限
1.5. 什么是抽象什么是实现
- CS研究的是问题,问题的解决过程和问题的解决方案
- 为了更好地处理机器相关性和独立性,引入了抽象的概念
- 从 “ 逻 辑 Logical ” 或 者 “ 物 理
Physical”的不同层次上看待问题及解决
方案 - 逻辑:功能层次
- 物理:比如对硬件的内部处理知识
- 逻辑和物理是相对概念
- 不会有太多与当前层次的问题无关的细节
- 电动车与汽油车:
底层动力、能源都不同
但开车的操作接口(方向盘、油门、刹车、档位
)基本都是相同的
司机无需重新考驾照,而车厂可以持续改进实现
技 - 与此同时,物理层面可以保持改进
1.6. 为什么研究数据结构
- ADT是对数据进行处理的一种逻辑描述,并不涉及如何实现这些处理
1.7. 书籍补充
- 定义类
class Fraction:
#定义方法
def __init__(self,top,buttom):
self.num = top
self.den = buttom
#self是一个总指向对象本身的特殊参数,必须是1st
#要创建类,必须调用构造方法e.g.
#myfraction = Fraction(3,5)
def show(self):
print(self.num,"/",self.den)
#print(myfraction)是地址
#print(myfraction.show)才是3/5
#重写默认实现
def __str__(self):
return str(self.num) + "/" + str(self.den)
#myf = Fraction(3,5)
#print(myf)成了3/5
#myf.__str__()为'3/5'
#str(myf)为'3/5'
#**重写加法**
def __add__(self,otherfraction):
newnum = self.num * otherfraction.den + \
self.den * otherfraction.num
newden = self.den * otherfraction.den
common = gcd(newnum,newden)
return Fraction(newnum//common,newden//common)
#重写相等
#只有在f1和f2是同一个对象的引用时,f1==f2才是True(浅相等);值相等才是深相等
def __eg__(self,other):
firstnum = self.num * other.den
secondnum = self.den * other.num
return firstnum == secondnum
#最简分数
def gcd(self,m,n):
while m%n != 0:
oldm = m
oldn = n
m = oldn
n = oldm%oldn
return n
二.第二章
这一章也是基础内容,讲了时间复杂度的计算。非常有意思。计算执行语句。在排序的时候,就是用的赋值操作来计算。
2.1. 什么是算法分析
- 算法:是对问题解决的分步描述【逻辑层面】
程序则是采用某种编程语言实现的算法,同一个 - 程序:算法通过不同的程序员采用不同的编程语言,能产生很多程序【物理层面】
- 比较程序的“好坏”,有更多因素:代码风格、可读性等等
- 我们主要感兴趣的是算法本身特性
- 算法分析主要就是从计算资源(执行时间、存储空间)消耗的角度来评判和比较算法。更高效利用计算资源,或者更少占用计算资源的算法,就是好算法
- 但是不同的编程语言和程序,会导致执行时间不同,因此使用时间复杂度来衡量
2.2. 大O表示法
- 一个算法所实施的操作数量或步骤数可作为
独立于具体程序/机器的度量指标
- 使用哪种操作来衡量?
==>需要一种通用的基本操作来作为运行步骤的计量单位
- 使用赋值语句作为衡量指标
- 因为同时包含了(表达式)计算和(变量)存储
- 控制流语句(顺序、决策和循环)只是组织语句,本身不实行处理
- 定义语句与计算资源无关
- 问题规模影响算法执行时间。算法分析的目标是找出问题规模怎么影响一个算法的执行时间
- 数量级函数描述了基本操作数量函数T(n)中随着n增加而增加速度最快的主导部分。称作“大O”表示法,记作O(f(n)),其中f(n)表示T(n)中的主导部分。也就是看n的情况
- 某些具体数据也会影响算法运行时间,因此分为最好、最差和平均的情况。平均情况是算法的主流性能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xE32Dnm2-1622898540145)(/img/1.png)]
7. 大O表示法:所有上限中最小的上限
8. 大表示法:所有下限中最大的下限
9. 大表示法:如果上下限相同
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KVZMqIHh-1622898540147)(/img/2.png)]
2.3. 变位词的判断问题
- 变位词两个次之间存在组成字母的重新排列关系,eg.heart和earth
- 这个是举例子来计算
2.4. python数据类型的性能
- list和dict
- 列表是随机访问的,取值赋值的时间是O(1)
- 列表增加,append是O(1),列表链接是O(n+k)。n是原列表长度,k是新列表长度
- 列表判断in 是O(n),dic是O(1)
2.5. 如何做OJ
- 输出必须一致,包括看不见的空格
- 如何做
- 看清题
- 看清样例的格式
a. 多行输入:每行一个input()
,根据要求转换。若每行一个整数a = int(input())
b. 单行输入多个变量,用input().split()
读入并分解为列表
c. 多个整数在一行list(map(int,input().split()))
d. 多行输出:print
e. 浮点数指定:看清保留小数点后几位,用print('%.3f'%(a/b))
来规定 - 编写程序与测试
- 提交测评
2.6. 列表
- 生成列表速度从快到慢
l1 = list(range(1000))
l2 = [i for i in range(1000)]
l3 = []
for i in range(1000):
l3.append(i)
l4 = []
for i in range(1000):
l4 += [i]
- 操作的时间复杂度
2.7. 字典
- 生成字典
for i in range (10000,1000001,20000):#start,end,step
x = {j:None for j in range(i) }
for key,value in x.items():
print((key,value))
*操作的时间复杂度
三.第二周OJ
题目1.
题目内容:
给出两个整数,输出他们的商
可以使用以下语句实现整数n的输入:
n=int(input())
输入格式:
两行,每行一个整数
输出格式:
输出一个数,即他们的商,保持小数点后3位(%.3f)
如果除数为0,则输出:NA(两个字母)
输入样例:
1
2
输出样例:
0.500
输入样例2:
2
0
输出样例2:
NA
时间限制:500ms内存限制:32000kb
a = int(input())
b = int(input())
if b != 0:
print('%.3f'%(a/b))
else:
print('NA')
题目2.
题目内容:
给出行数和列数,打印一个由*号构成的实心矩形。
输入格式:
一行,用空格隔开的两个整数m、n
输出格式:
由*号构成的m行n列实心矩形
输入样例:
3 2
输出样例:
**
**
**
时间限制:500ms内存限制:32000kb
m,n = map(int,input().split())
for i in range(1,m+1):
print('*'*n)
题目3.
题目内容:
给定若干个整数,找出这些整数中最小的,输出。
输入格式:
一行,由空格隔开的一系列整数,数量2个以上。
输出格式:
最小的整数
输入样例:
1 2 3 4 5 6 7 8 9 0
输出样例:
0
输入样例:
-1 2 0
输出样例:
-1
时间限制:500ms内存限制:32000kb
a = list(map(int,input().split()))
print(min(a))
四. 总结
这些比较重要的入门基础还是要看看,我就只记录我需要的部分