算法 初识

Posted zaizai1573

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法 初识相关的知识,希望对你有一定的参考价值。

什么是算法 如何理解算法?

算法就是对问题进行处理且求解的一种实现思路或者思想。

  • 一个常胜将军在作战之前都会进行战略的制定,目的是为了能够在最短的时间切成本消耗最低的情况下获取最终的胜利。如果将编码作为战场,则程序员就是这场战役的指挥官,你如何可以将你的程序可以在最短且消耗资源最小的情况下获取最终的执行结果呢?算法就是我们的策略!

什么是算法分析?

  • 刚接触编程的学生经常会将自己编写的程序和别人的程序做比对,获取在比对的过程中会发现双方编写的程序很相似但又各不相同。那么就会出现一个有趣的现象:两组程序都是用来解决同一个问题的,但是两组程序看起来又各不相同,那么哪一组程序更好呢?
  • a+b+c = 1000 a2 + b2 = c**2 (a,b,c均为自然数),求出a,b,c可能的组合?
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)

代码二

for a in range(0,1001):
    for b in range(0,1001):
        c = 1000 - a - b
        if a**2 + b**2 == c**2 and a+b+c==1000:
            print(a,b,c)

可以看出 相同的结果 不同的代码 时长不一样

评判程序优势的方法

  • 消耗计算机资源和执行效率(无法直观)
  • 计算算法执行的耗时(适当推荐,因为会受机器和执行环境的影响)
  • 时间复杂度(推荐)

时间复杂度:

  • 评判规则:量化算法执行的操作/执行步骤的数量
  • 最重要的项:时间复杂度表达式中最有意义的项
  • 大O记法:O(时间复杂度表达式中最有意义的项)

计算下列算法的时间复杂度

a=5
b=6
c=10
for i in range(n):
   for j in range(n):
      x = i * i
      y = j * j
      z = i * j
for k in range(n):
   w = a*k + 45
   v = b*b
d = 33

3+3n**2+2n+1

O(n**2)

常见的时间复杂度:

  • O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

数据结构

  • 案例: 需要存储一些学生的学生信息(name,score),那么这些数据应该如何组织呢?查询某一个具体学生的时间复杂度是什么呢?(三种组织方式)
[
    [tom,100],[jay,99]
]
#O(n)
[
    (tom,100),(jay,99)
]
#O(n)

    tom:score:100,
    jay:score:100,

#O(1)

如何测试代码性能?

  • timeit模块:该模块可以用来测试一段python代码的执行速度/时长。

  • Timer类:该类是timeit模块中专门用于测量python代码的执行速度/时长的。原型为:class timeit.Timer(stmt=‘pass‘,setup=‘pass‘)。

    • stmt参数:表示即将进行测试的代码块语句。

    • setup:运行代码块语句时所需要的设置。

    • timeit函数:timeit.Timer.timeit(number=100000),该函数返回代码块语句执行number次的

    • 计算运行平局耗时
    •  

      from timeit import Timer
      
      def test01():
          alist = []
          for i in range(1000):
              alist.append(i)
      
      def test02():
          alist = []
          for i in range(1000):
              alist += [i]
      
      def test03():
          alist = [i for i in range(1000)]
      
      def test04():
          alist = list(range(1000))
      
      def test05():
          alist = []
          for i in range(1000):
              alist.insert(i, i)
      
      if __name__ == __main__:
          timer = Timer(stmt=test01(), setup=from __main__ import test01)
          print(timer.timeit(1000))
          timer = Timer(stmt=test02(), setup=from __main__ import test02)
          print(timer.timeit(1000))
          timer = Timer(stmt=test03(), setup=from __main__ import test03)
          print(timer.timeit(1000))
          timer = Timer(stmt=test04(), setup=from __main__ import test04)
          print(timer.timeit(1000))
          timer = Timer(stmt=test05(), setup=from __main__ import test05)
          print(timer.timeit(1000))
      ########################
      0.1200843300920747
      0.09542515960902793
      0.035514636978769026
      0.022534339526118885
      0.178243830964033

先进后出的数据结构

栈顶,栈尾

技术图片

Stack()创建一个空的新栈,他不需要参数,并返回一个空栈
push(item)将一个新项添加到栈的顶部,它需要item做参数并不不返回任何内容
pop()从栈中删除顶部的项,它不需要参数返回item,栈被修改
peek()从栈返回顶部项,但不会删除
isEmpty()测试栈是否为空,不需要参数,并返回布尔值
size()返回栈中的item数量,不需要参数,并返回一个整数
class Stack():
    def __init__(self):
        self.items=[]
    def push(self,item):
        self.items.append(item)
    def pop(self):
        return self.items.pop()
    def peek(self):
        return self.items[-1]
    def isEmpty(self):
        return self.items==[]
    def size(self):
        return len(self.items)
s=Stack()
s.push(test1)
s.push(test2)
s.push(test3)
print(s.pop())
print(s.pop())
print(s.peek())#返回栈的顶部
print(s.isEmpty())#判断是否为空
print(s.size())#返回栈的数量

网页回滚

s=Stack()
def request(url):
    s.push(url)
def back():
    print(s.pop())
request(wwwbaidu1.com)
request(www.baidu2.com)
back()
back()
######
www.baidu2.com
wwwbaidu1.com

队列

先进先出

Queue()创建一个空的新队列,它不要参数

enqueue(item)将新项添加到队尾,它需要item作为参数

dequeue()从队首移除项,它不需要参数并返回item

isEmpry()查看队列是否为空 并返回布尔值

size()返回队列中的项书 并返回一个整数

class Queue():
    def __init__(self):
        self.items=[]
    def enqueue(self,item):
        self.items.insert(0,item)
    def dequeue(self):
        return  self.items.pop()
    def isEmpty(self):
        return self.items==[]#判断是否为空
    def size(self):
        return len(self.items)
q=Queue()#创建一个空对列
q.enquequ(1)
q.enquequ(2)
q.enquequ(3)
print(q.dequeue())
print(q.dequeue())

1

2

烫手的山芋

烫手山芋游戏介绍:6个孩子围城一个圈,排列顺序孩子们自己指定。第一个孩子手里有一个烫手的山芋,需要在计时器计时1秒后将山芋传递给下一个孩子,依次类推。
规则是,在计时器每计时7秒时,手里有山芋的孩子退出游戏。该游戏直到剩下一个孩子时结束,最后剩下的孩子获胜。请使用队列实现该游戏策略,排在第几个位置最终会获胜。

技术图片技术图片

class Queue():
    def __init__(self):
        self.items=[]
    def enqueue(self,item):
        self.items.insert(0,item)
    def dequeue(self):
        return  self.items.pop()
    def isEmpty(self):
        return self.items==[]#判断是否为空
    def size(self):
        return len(self.items)

q = Queue()
alist = [a, b, c, d, e, f]
for i in alist:
    q.enqueue(i)#把6个孩子加入队列

while q.size() > 1:#循环队列大于一就跑
    for i in range(6):#次数
        kid = q.dequeue()#让对头的孩子退出队列
        q.enqueue(kid)#在让加入队列
    q.dequeue()#第6次之后 永久性退出循环
#结束之后 把这个孩子取出
print(q.dequeue())

双端队列

  • 同同列相比,有两个头部和尾部。可以在双端进行数据的插入和删除,提供了单数据结构中栈和队列的特性

 Deque()创建一个空的新deque,他不需要任何参数

addFront(item)将一个新项添加到deque的首部,他需要item参数

addRear(item)将一个新项添加到deque的尾部它需要iem参数

removeFront()从deque中删除首项,它不需要参数并返回item

removeRear()从deque中删除尾项,它不需要参数并返回item

isEmpty()测试deque是否为空,它不需要参数,并返回布尔值

size()返回deque中的项说,它不需要参数,并返回一个整数

 

以上是关于算法 初识的主要内容,如果未能解决你的问题,请参考以下文章

Java初识方法

初识OpenGL 片段着色器(Fragment Shader)

初识OpenGL 片段着色器(Fragment Shader)

初识OpenGL (-)纹理(Texture)

初识OpenGL (-)纹理(Texture)

初识OpenGL (-)纹理(Texture)