算法就相当于军师在排兵布阵
# 枚举法--暴力破解
import time
start_time = time.time()
# 循环嵌套
for a in range(0,1001):
for b in range(0,1001):
for c in range(0,1001):
if a**2 + b**2 == c**2 and a + b + c == 1000:
print('a,b,c:%d,%d,%d'%(a,b,c))# 格式化的方式
end_time = time.time()
print('times:%f'%(end_time-start_time))
print('end')
运行时间会很长,实际上这就是算法。
import time
start_time = time.time()
for a in range(0,1001):
for b in range(0,1001-a):
c = 1000- a - b
print('a,b,c:%d,%d,%d'%(a,b,c))
end_time = time.time()
print('times:%f'%(end_time- start_time))
print('end')
运行结果:
a,b,c:0,500,500
a,b,c:200,375,425
a,b,c:375,200,425
a,b,c:500,0,500
times:0.748054
end
简化的思想:因为a+b+c = 1000,所以在循环嵌套的第一层,确定了a的值,所以可以确定b=1000-a,第二层循环确定了b = 1000-a,而c=1000-a-b,所以c的值就确定了,这样代码就会很便捷,运行时间变少。
算法的执行效率就是算法代码的执行时间
虽然每台机器的执行总时间不同,但是每台电脑的执行的基本运算大体是相同的。
如下:
for i in range(2):
for i in range(3):
print(i,j)
0 0
0 1
0 2
1 0
1 1
1 2
由此可见i和j是一个相乘的关系。
再回到上面的代码中
for a in range(0,1001):
for b in range(0,1001):
for c in range(0,1001):
if a**2 + b**2 == c**2 and a + b + c == 1000:
print('a,b,c:%d,%d,%d'%(a,b,c))# 格式化的方式
# a执行1000次,b执行1000次,c也执行1000次,if语句执行2次
# 所以时间T(n) = 1000 * 1000 * 1000 * 2
# 如果将1000换成n则时间T(n) = n^3 *2
# n^3*2看成是f(n)
# T(n) = f(n)*2
# T(n) = O(f(n))
所有代码的执行时间T(n)与每行代码的执行次数n成正比
T(n) = O(f(n))
公式中的低阶、常量、系数三部分并不能左右增长趋势,所以都可以忽略,只需要记录一个最大的量级就可以了
def cal(n):
sum = 0
i = 1
for i in range(n + 1):
sum += i
i += 1
return sum
# T(n) = O(n)
def cal(n):
sum = 0
i = 1
for i in range(100):
sum += i
for i in range(n+1):
sum += i
i+= 1
for i in range(n+1):
for j in range(n +1):
pass
# T(n) = max(O(1) + O(n) + O(n^2)) = O(n^2)
综合三段代码的时间复杂度,得出整段代码的时间复杂度T(n) = f(n^2),所以总的时间复杂度就等于量级最大的那段代码的时间复杂度。
在分析算法的时候,存在几种可能的考虑:
# 如果按从小到大开始排列
li1 = [1,2,3,4,5]# T(n) = O(1) 最优的时间复杂度
li2 = [5,4,3,2,1]# T(n) = O(n) 最坏的时间复杂度
li =[]
li.append()
li.insert()
timeit模块
timeit模块用来测试一小段Python代码的执行速度
class timeit.Timer(stmt = ‘pass’,setup = ‘pass’,timer = )
Timer 是测量小段代码执行速度的类
stmt参数是要测试的代码语句(statment);
setup参数是运行代码时需要的设置
timer参数是一个定时器函数,和平台有关
timeit.Timer.timeit(number = 1000000)
Timer类中测试语句执行速度的对象方法。
list的操作测试
def ts1():
l = []
for i in range(1000):
l = l + [i]
def ts2():
l = []
for i in range(1000):
l.append(i)
def ts3():
l = [i for i in range(1000)]
def ts4():
l = list(range(1000))
def ts5():
l = []
for i in range(1000)
l.insert(0,i)
from timeit import Timer
t1 = Timer("ts1()","from __main__ import ts1")
print("add",t1.timeit(number = 1000))
t2 = Timer("ts2()","from __main__ import ts2")
print("append",t2.timeit(number = 1000))
t3 = Timer("ts3()","from __main__ import ts3")
print("list derivation",t3.timeit(number = 1000))
t4 = Timer("ts4()","from __main__ import ts4")
print("list range",t4.timeit(number = 1000))
t5 = Timer("ts5()","from __main__ import ts5")
print("list insert",t5.timeit(number = 1000))
那么我们如何用Python中的类型来保存一个班的学生信息呢?
"""
第一种方式
{
'zhangsan':{
'age':18,
'address':'css'
}
}
第二种方式
[
('zhangsan',18,'dff'),
('lisi',17,'der'),
('zhaowu',19,'dfg')
]
第三种方式
[
{
'name':'zhangsan',
'age':18,
'address':'hkl'
}
]
"""
数据结构是静态的描述了数据元素之间的关系
高效的程序需要在数据结构的基础上设计和选择算法
程序 = 数据结构 + 算法
算法是为了解决实际问题而进行设计的,数据结构是算法需要处理的问题载体。
抽象数据类型的含义是指一个数学模型以及定义在此数学模型上的一组操作,就是把数据类型和数据类型上的运算捆绑在一起,进行封装
"""
第一种方式
{
'zhangsan':{
'age':18,
'address':'afd'
}
}
第二种方式
[
('zhangsan',18,'dff'),
('lisi',17,'der'),
('zhaowu',19,'dfg')
]
第三种方式
[
{
'name':'zhangsan',
'age':'18',
'address':'hkl'
}
]
"""
class stu(object):
def add(self):
pass
def pop(self):
pass
def sort(self):
pass
def modify(self):
pass
上述代码中:
class类相当于一个模型,而def这些定义的函数,比如add pop sort modify就相当于模型上的操作