Python基础语法(6)

算法学习

利用栈进项进制转换与递归进制转换

class Stack:
    def __init__(self):
        self.items = []
    def is_empty(self):
        return self.items == []
    def push(self, item):
        self.items.append(item)
    def pop(self):
        return self.items.pop()
    def peek(self):
        return self.items[len(self.items) - 1]
    def size(self):
        return len(self.items)

def to_str16(n,base):  #进制转换
    convert_string="0123456789ABCDEF"
    if n<base:
        return convert_string[n]
    else:
        return to_str16(n//base,base)+convert_string[n%base]

r_stck=Stack()
def to_str(n,base):  #当一个函数被调用时系统分配一个栈帧处理局部变量
    convert_stirng="0123456789ABCDEF"
    while n>0:
        if n<base:
            r_stck.push(convert_stirng[n])
        else:
            r_stck.push(convert_stirng[n%base])
        n=n//base
    res=""
    while not r_stck.is_empty():
        res = res+str(r_stck.pop())
    return res
reverse方法实现
def return_string(str):  #reverse方法实现
    if len(str) <= 1:
        return str
    else:
        return return_string(str[1:])+str[0]

图形递归

import turtle

my_turtle = turtle.Turtle()
my_win = turtle.Screen()

def draw_spiral(tur, line_len):  #正方形
    if line_len > 0:
        my_turtle.forward(line_len)
        my_turtle.right(90)
        draw_spiral(tur, line_len - 1)


#draw_spiral(my_turtle, 100)
#my_win.exitonclick()

# my_tree = turtle.Turtle()
# my_win = turtle.Screen()


def draw_tree(branch_length, t):
    if branch_length > 5:
        t.forward(branch_length)
        t.right(20)
        draw_tree(branch_length-20, t)
        t.left(40)
        draw_tree(branch_length-20, t)
        t.right(20)
        t.backward(branch_length)


# my_tree.left(90)
# my_tree.up()  # 抬起尾巴
# my_tree.backward(200)
# my_tree.down()  # 放下尾巴
# my_tree.color('green')
# draw_tree(100, my_tree)
# my_win.exitonclick()

#print(return_string("asda"))

def draw_triangle(points, color, my_angle):
    my_angle.fillcolor(color)
    my_angle.up()
    my_angle.goto(points[0][0], points[0][1])
    my_angle.down()
    my_angle.begin_fill()
    my_angle.goto(points[1][0], points[1][1])
    my_angle.goto(points[2][0], points[2][1])
    my_angle.goto(points[0][0], points[0][1])
    my_angle.end_fill()


def getMid(p1, p2):
    return ((p1[0]+p2[0])/2, (p1[1]+p2[1])/2)


def sierpinski(points,degree,myTurtle):
    colormap=['blue','red','green','white','yellow','violet','orange']
    draw_triangle(points,colormap[degree],myTurtle)
    if degree>0:
        sierpinski([points[0],getMid(points[0],points[1]),getMid(points[0],points[1])],degree-1,myTurtle)
        sierpinski([points[1], getMid(points[0], points[1]), getMid(points[1], points[2])], degree - 1, myTurtle)
        sierpinski([points[2],getMid(points[2],points[1]),getMid(points[0],points[2])],degree-1,myTurtle)

# my_turtle=turtle.Turtle()
# Win=turtle.Screen()
# myPoints=[[-100,-50],[0,100],[100,-50]]
# sierpinski(myPoints,3,my_turtle)
# Win.exitonclick()

硬币找零算法

def recMC(coinValueList,change):
    minCoins=change
    if change in coinValueList:
        return 1
    else:
        for i in [c for c in coinValueList if c<=change]:  #限定找零不能找面值过大的
            numCoins=1+recMC(coinValueList,change-i)
            if numCoins<minCoins:  #计算所得的numCoins>
                minCoins=numCoins
    return minCoins
#print(recMC([1,5,10,25],63))
#上述算法感觉过于重复,计算时间太长了
def recDC(coinValueList,change,knownResults):#查表法递归
    minCoins=change
    if change in coinValueList:
        knownResults[change]=1
        return 1
    elif knownResults[change]>0:
        return knownResults[change]
    else:
        for i in [c for c in coinValueList if c<=change]:
            numCoins=1+recDC(coinValueList,change-1,knownResults)
            if numCoins<minCoins:
                minCoins=numCoins
                knownResults[change]=minCoins
    return minCoins
#print(recDC([1,5,10,25],63,[0]*64))

#硬币找零算法
def dpMakeChange(coinValueList,change,minCoins,coinsUsed):
    for cents in range(change+1):
        coinCount=cents
        newCoin=1
        for j in [c for c in coinValueList if c<=cents]:
            if minCoins[cents-j]+1<coinCount:
                coinCount=minCoins[cents-j]+1
                newCoin=j
        minCoins[cents]=coinCount
        coinsUsed[cents]=newCoin
    return minCoins[change]

def printCoins(coinUsed,change):
    coin=change
    while coin>0:
        thisCoin=coinUsed[coin]
        print(thisCoin)
        coin=coin-thisCoin

def main():
    amnt=63
    clist=[1,5,10,21,25]
    coinUsed=[0]*(amnt+1)
    coinCount=[0]*(amnt+1)
    print("Makeing change for",amnt,"requires")
    print(dpMakeChange(clist,amnt,coinCount,coinUsed),"coins")
    print("They are:")
    printCoins(coinUsed,amnt)
    print("The used list is as follow:")
    print(coinUsed)

二分法检索

def sequentialSearch(alist,item):  #一一比对检索
    pos=0
    found=False
    while pos<len(alist) and not found:
        if alist[pos]==item:
            found=True
        else:
            pos=pos+1
    return found

def orderdSequentialSearch(alist,item):
    pos=0
    found=False
    stop=False
    while pos<len(alist) and found and not stop:
        if alist[pos]==item:
            found=True
        else:
            if alist[pos]>item:
                stop=True
            else:
                pos=pos+1
    return found

def binarySearch(alist,item):  #顺序表二分法
    first=0
    last=len(alist)-1
    found=False
    while first<=last and not found:
        midpoint=(first+last)/2
        if alist[midpoint]==item:
            found=True
        else:
            if item<alist[midpoint]:
                last=midpoint-1
            else:
                first=midpoint+1
    return found
    
def binarySearch(alist,item):  #递归调用实现二分法,复杂度O(log(n))
    if len(alist)==0:
        return False
    else:
        midpoint=len(alist)/2
        if alist[midpoint]==item:
            return True
        else:
            if item<alist[midpoint]:
                return binarySearch(alist[:midpoint],item)
            else:
                return binarySearch(alist[midpoint+1:],item)

有趣的数据结构

#散列表是一种数据集合,每个数据都通过特定的方式进行储存,位置叫槽
#数据项和在散列表中存储它的槽直接的映射叫做散列函数。散列函数可以将任意一个数据项存储到集合中并返回一个介于槽命名区间内的(0-1)的整数

#折叠法创建散列函数:将数据分成相同长度的片段(最后一段可能),然后将这些片段相加,在求余得到散列值
def hash(astring,tablesize):  #用ASCII码散列字符
    sum=0
    for pos in range(len(astring)):
        sum=sum +ord(astring[pos])
    return sum%tablesize

# print(hash('cat',11))
#针对冲突问题,通过开放地址和线性探测再散列,rehash(pos)=(pos+skip)%sizeftable,注意skip的数值必须保证所有的槽都被遍历,所以设槽设置为质数
class HashTable:
    def __init__(self):
        self.size=11
        self.slots=[None]*self.size  #槽,用来储存密钥
        self.data=[None]*self.size  #存数据

    def put(self,key,data):
        hashvalue=self.hashfunction(key,len(self.slots))
        if self.slots[hashvalue]=None:
            self.slots[hashvalue]=key
            self.data[hashvalue]=data
        else:
            if self.slots[hashvalue]==key:  #replace
                self.data[hashvalue]=data
            else:
                nextslot=self.rehash(hashvalue,len(self.slots))
                while self.slots[nextslot]!=None and self.slots[nextslot]!=key:
                    nextslot=self.rehash(nextslot,len(self.slots))
                if self.slots[nextslot]==None:
                    self.slots[nextslot]=key
                    self.data[nextslot]=data
                else:
                    self.data[nextslot]=data #replace

    def hashfunction(self,key,size):
        return key%size
    def rehash(self,oldhash,size):
        return (oldhash+1)%size

    def get(self,key):
        startslot=self.hashfunction(key,len(self.slots))
        data=None
        stop=False
        found=False
        position=startslot
        while self.slots[position]!=None and not found and not stop:
            if self.slots[position]==key:
                found=True
                data=self[position]
            else:
                position=self.rehash(position,len(self.slots))
                if position==startslot:
                    stop=True
        return data
    def __getitem__(self, key):
        return self.get(key)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值