《Python数据结构与算法分析》学习笔记

目录

  • 第一章 导论
    • 1.4 Python数据
      • 1.4.1 内建集合数据类型
        • 1.4.1.1 列表
        • 1.4.1.2 字符串
        • 1.4.1.3 集合
        • 1.4.1.4 字典
      • 1.4.3 控制结构
      • 1.4.6 定义类
        • 1.4.6.1 Fraction类
        • 1.4.6.2 继承:逻辑门与电路
    • 1.8 练习题

第一章 导论

介绍抽象数据类型,复习Python。

1.4 Python数据

1.4.1 内建集合数据类型

1.4.1.1 列表

运算:索引([ ])、连接(+)、重复(*)、成员(in)、长度(len)、切片([:])
方法:append、insert、pop、sort、reverse、del、index、count、remove。
del(l[index]):删除索引号index的元素,无返回值
l.pop():删除最后一个值,并返回
l.remove(item):移除列表中第一次出现的item

1.4.1.2 字符串

方法:.center(w); .count(item); .ljust(w); .rjust(w); .lower(); .upper(); .find(item); .split(schar)

1.4.1.3 集合

运算:成员(in)、长度(len)、|、&、<=、-
方法:.union(otherset)、 .intersection(.otherset)、 .issubset(otherset)、 .difference(otherset); .add(item); .remove(item); .pop(); .cleat()

1.4.1.4 字典

运算符:[ ]、in、del
方法:.keys(); .values(); .items(), .get(key); .get(key, alt)

1.4.3 控制结构

列表解析式:
sqlist = [x*x for x in range(1,11) if x%2 !=0]

1.4.6 定义类

1.4.6.1 Fraction类

class Fraction:
    # 构造方法
    def __init__(self, top, bottom):
        '''
        top: 分子
        bottom: 分母
        '''
        if all([isinstance(x,int) for x in [top,bottom]]):
            common = self.gcd(top,bottom)
            label = (top*bottom)//abs(top*bottom)
            self.num = label*abs(top//common)
            self.den = abs(bottom//common)
        else:
            raise TypeError("分子分母必须都为整数")
    # str(),print() 给用户看的,用于显示内容
    def __str__(self):
        return "{}/{}".format(self.num,self.den)
    
    # repr(),Fraction 用于调试和开发,复现obj = eval()
    def __repr__(self):
        return "Fraction({},{})".format(self.num,self.den)
    
    # 加法 
    def __add__(self,otherfraction):
        newnum = self.num*otherfraction.den+self.den*otherfraction.num
        newden = self.den * otherfraction.den
        # common = self.gcd(newnum,newden)
        # return Fraction(newnum//common,newden//common)
        return(Fraction(newnum,newden))
     
    # 右加 
    def __radd__(self,otherfraction):
        newnum = self.num*otherfraction.den+self.den*otherfraction.num
        newden = self.den * otherfraction.den
        return(Fraction(newnum,newden))
        
    # +=
    # def __iadd__(self,otherfraction):
        ## newnum = self.num*otherfraction.den+self.den*otherfraction.num
        ## newden = self.den * otherfraction.den
        # self = (Fraction(newnum,newden))
        # self = self.__add__(self,otherfraction) 
        
    # 减法
    def __sub__(self,otherfraction):
        return self.__add__(Fraction(-otherfraction.num,
        otherfraction.den))
    
    # 乘法
    def __mul__(self,otherfraction):
        newnum = self.num * otherfraction.num
        newden = self.den * otherfraction.den
        return Fraction(newnum, newden)
        
    # 除法
    def __truediv__(self,otherfraction):
        return self.__mul__(Fraction(otherfraction.den, 
        otherfraction.num))
    
    
    # 等于
    def __eq__(self,other):
        first = self.num * other.den
        second = other.num * self.den
        return first == second
        
    # 不等
    def __ne__(self,other):
        first = self.num * other.den
        second = other.num * self.den
        return first != second
        
    # 大于
    def __gt__(self,other):
        first = self.num * other.den
        second = other.num * self.den
        return first > second    
    
    # 大于等于
    def __ge__(self,other):
        first = self.num * other.den
        second = other.num * self.den
        return first >= second     

    # 小于
    def __lt__(self,other):
        first = self.num * other.den
        second = other.num * self.den
        return first < second    

    # 小于等于
    def __le__(self,other):
        first = self.num * other.den
        second = other.num * self.den
        return first <= second            
    
    # 求解最大公因子
    def gcd(self,m,n):
        while m % n!=0:
            oldm = m
            oldn = n
            
            m = oldn
            n = oldm%oldn
        return n
        
    # 返回分子
    def getNum(self):
        return self.num
    
    # 返回分母:
    def getDen(self):
        return self.den
        
    # 复制
    def copy(self):
        return Fraction(self.num,self.den)
if __name__=="__main__":
    f1 = Fraction(4,5)
    print(f1)
    f2 = Fraction(2,-4)
    print(f2)

    print("f1+f2:", f1+f2)
    print("f1-f2:", f1-f2)
    print("f1*f2:", f1*f2)
    print("f1/f2:", f1/f2)
    f1+=f2
    print("f1+=f2", f1)
    print("==",f1==f2)
    print("!=",f1!=f2)
    print(">",f1>f2)
    print(">=",f1>=f2)
    print("<",f1<f2)
    print("<=",f1<=f2)

结果:

4/5
-1/2
f1+f2: 3/10
f1-f2: 13/10
f1*f2: -2/5
f1/f2: -8/5
f1+=f2 3/10
== False
!= True
> True
>= True
< False
<= False

在命令行中输入变量名显示__repr__:

>>> from Fraction import Fraction
>>> f1 = Fraction(-3,2)
>>> f1
Fraction(-3,2)
>>>

1.4.6.2 继承:逻辑门与电路

IS-A用于描述子类和父类关系

# 超类LogicGate
class LogicGate:

    def __init__(self,n):
        self.label = n
        self.output = None
    
    def getLabel(self):
        return self.label
        
    def getOutput(self):
        self.output = self.performGateLogic()
        return self.output
        
# 二引脚逻辑门
class BinaryGate(LogicGate):

    def __init__(self,n):
        super().__init__(n)
        
        self.pinA = None
        self.pinB = None
        
    def getPinA(self):
        return int(input("Enter Pin A for gate" + self.getLabel() + "-->"))
        
    def getPinB(self):
        return int(input("Enter Pin B for gate" + self.getLabel() + "-->"))
        

# 单引脚逻辑门
class UnaryGate(LogicGate):
    
    def __init__(self,n):
        super().__init__(n)
        
        self.pin = None
        
    def getPin(self):
        return int(input("Enter Pin for gate" + self.getLabel() + "-->"))     
        
# 与门
class AndGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
        
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == 1 and self.pinB == 1:
            return 1
        else:
            return 0
 
# 或门
class OrGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
        
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == 1 or self.pinB == 1:
            return 1
        else:
            return 0 
# 非门
class NotGate(UnaryGate):
    def __init__(self,n):
        super().__init__(n)
        
    def performGateLogic(self):
        self.pin = self.getPin()
        if self.pin==1:
            return 0
        else:
            return 1



if __name__=="__main__":
    g1 = AndGate("G1")
    print(g1.getOutput())
    g2 = OrGate("G2")
    print(g2.getOutput())
    g3 = NotGate("G3")
    print(g3.getOutput())

HAS-A关系 (HAS-A意即“有一个”)
连接器

# 超类LogicGate
class LogicGate:

    def __init__(self,n):
        self.label = n
        self.output = None
    
    def getLabel(self):
        return self.label
        
    def getOutput(self):
        self.output = self.performGateLogic()
        return self.output
        
# 二引脚逻辑门
class BinaryGate(LogicGate):

    def __init__(self,n):
        super().__init__(n)
        
        self.pinA = None
        self.pinB = None
        
    def getPinA(self):
        if self.pinA == None:
            return int(input("Enter Pin A for gate" + self.getLabel() + "-->"))
        else:
            return self.pinA.getFrom().getOutput()
        
    def getPinB(self):
        if self.pinB == None:
            return int(input("Enter Pin B for gate" + self.getLabel() + "-->"))
        else:
            return self.pinB.getFrom().getOutput()

    def setNextPin(self,source):
        if self.pinA == None:
            self.pinA = source
        else:
            if self.pinB == None:
                self.pinB = source
            else:
                raise RuntimeError("Error: NO EMPTY PINS")
        

# 单引脚逻辑门
class UnaryGate(LogicGate):
    
    def __init__(self,n):
        super().__init__(n)
        
        self.pin = None
        
    def getPin(self):
        if self.pin == None:
            return int(input("Enter Pin for gate" + self.getLabel() + "-->"))   
        else:
            return self.pin.getFrom().getOutput()
        
    def setNextPin(self,source):
        if self.pin == None:
            self.pin = source
        else:
            print("Cannot Connect: NO EMPTY PINS on this gate")
        
# 与门
class AndGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
        
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == 1 and self.pinB == 1:
            return 1
        else:
            return 0
            
# 与非门
class NandGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
    
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == 1 and self.pinB == 1:
            return 0
        else:
            return 1
            
# 或非门
class NorGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
    
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == 0 and self.pinB == 0:
            return 1
        else:
            return 0
    
 
# 或门
class OrGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
        
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == 1 or self.pinB == 1:
        # pinA = self.getPinA()
        # pinB = self.getPinB()
        # if pinA == 1 or pinB == 1:
            return 1
        else:
            return 0 
            
# 异或门
class NorGate(BinaryGate):
    
    def __init__(self,n):
        super().__init__(n)
    
    def performGateLogic(self):
        self.pinA = self.getPinA()
        self.pinB = self.getPinB()
        if self.pinA == self.pinB:
            return 0
        else:
            return 1
            
# 非门
class NotGate(UnaryGate):
    def __init__(self,n):
        super().__init__(n)
        
    def performGateLogic(self):
        self.pin = self.getPin()
        if self.pin==1:
            return 0
        else:
            return 1

class Connector():
    def __init__(self,fgate,tgate):
        self.fromgate = fgate
        self.togate = tgate
        
        tgate.setNextPin(self)
        
    def getFrom(self):
        return self.fromgate
     
    def getTo(self):
        return self.togate
        


if __name__=="__main__":
    g1 = AndGate("G1")
    g2 = AndGate("G2")
    g3 = OrGate("G3")
    g4 = NotGate("G4")
    
    c1 = Connector(g1,g3)
    c2 = Connector(g2,g3)
    c3 = Connector(g3,g4)
    
    print(g4.getOutput())
    

1.8 练习题

  1. 实现简单的方法getNum 和getDen ,它们分别返回分数的分子和分母。
  2. 如果所有分数从一开始就是最简形式会更好。修改Fraction 类的构造方法,立即使用最大公因数来化简分数。注意,这意味着__add__
    不再需要化简结果。
  3. 实现下列简单的算术运算:submul 和__truediv__ 。
  4. 实现下列关系运算:gtgeltle 和__ne__ 。
  5. 修改Fraction 类的构造方法,使其检查并确保分子和分母均为整数。如果任一不是整数,就抛出异常。
  6. 我们假设负的分数是由负的分子和正的分母构成的。使用负的分母会导致某些关系运算符返回错误的结果。一般来说,这是多余的限制。请修改构造方法,使得用户能够传入负的分母,并且所有的运算符都能返回正确的结果。
  7. 研究__radd__ 方法。它与__add__ 方法有何区别?何时应该使用它?请动手实现__radd__ 。
  8. 研究__iadd__ 方法。它与__add__ 方法有何区别?何时应该使用它?请动手实现__iadd__ 。
  9. 研究__repr__ 方法。它与__str__ 方法有何区别?何时应该使用它?请动手实现__repr__ 。
  10. 研究其他类型的逻辑门(例如与非门、或非门、异或门)。将它们加入电路的继承层次结构。你需要额外添加多少代码?
  11. 最简单的算术电路是半加器。研究简单的半加器电路并实现它。 将半加器电路扩展为8位的全加器。
  12. 本章展示的电路模拟是反向工作的。换句话说,给定一个电路,其输出结果是通过反向访问输入值来产生的,这会导致其他的输出值被反向查询。这个过程一直持续到外部输入值被找到,此时用户会被要求输入数值。修改当前的实现,使电路正向计算结果。当收到输入值的时候,电路就会生成输出结果。
  13. 设计一个表示一张扑克牌的类,以及一个表示一副扑克牌的类。使用这两个类实现你最喜欢的扑克牌游戏。
  14. 在报纸上找到一个数独游戏,并编写一个程序求解。
# 电路正向计算&半加器
# 超类LogicGate
class LogicGate:

    def __init__(self,n):
        self.label = n
        self.output = None
    
    def getLabel(self):
        return self.label
        
    def getOutput(self):
        self.output = self.performGateLogic()
        return self.output
        
# 二引脚逻辑门
class BinaryGate(LogicGate):

    def __init__(self,n,pinA=None,pinB=None):
        super().__init__(n)
        
        self.pinA = pinA
        self.pinB = pinB
        self.output = self.getOutput()
        
    # def getPinA(self):
        # if self.pinA == None:
            # return int(input("Enter Pin A for gate" + self.getLabel() + "-->"))
        # else:
            # return self.pinA.getFrom().getOutput()
        
    # def getPinB(self):
        # if self.pinB == None:
            # return int(input("Enter Pin B for gate" + self.getLabel() + "-->"))
        # else:
            # return self.pinB.getFrom().getOutput()
            
    def __str__(self):
        return "{} - pinA: {}; pinA: {}; output: {}".format(self.label,self.pinA, self.pinB,self.output)

    def setNextPin(self,source):
        if self.pinA == None:
            self.pinA = source.output
        else:
            if self.pinB == None:
                self.pinB = source.output
            else:
                raise RuntimeError("Error: NO EMPTY PINS")
        

# 单引脚逻辑门
class UnaryGate(LogicGate):
    
    def __init__(self,n,pin=None):
        super().__init__(n)
        
        self.pin = None
        self.output = self.getOutput()
    # def getPin(self):
        # if self.pin == None:
            # return int(input("Enter Pin for gate" + self.getLabel() + "-->"))   
        # else:
            # return self.pin.getFrom().getOutput()
            
    def __str__(self):
        return "{} - pin: {}; output: {}".format(self.label,self.pin,self.output)

        
    def setNextPin(self,source):
        if self.pin == None:
            self.pin = source.output
        else:
            print("Cannot Connect: NO EMPTY PINS on this gate")
        
# 与门
class AndGate(BinaryGate):
    
    def __init__(self,n,pinA=None, pinB=None):
        super().__init__(n,pinA,pinB)
        
    def performGateLogic(self):
        # self.pinA = self.getPinA()
        # self.pinB = self.getPinB()
        if self.pinA == 1 and self.pinB == 1:
            return 1
        else:
            return 0
            
# 与非门
class NandGate(BinaryGate):
    
    def __init__(self,n,pinA=None, pinB=None):
        super().__init__(n,pinA,pinB)
    
    def performGateLogic(self):
        # self.pinA = self.getPinA()
        # self.pinB = self.getPinB()
        if self.pinA == 1 and self.pinB == 1:
            return 0
        else:
            return 1
            
# 或门
class OrGate(BinaryGate):
    
    def __init__(self,n,pinA=None, pinB=None):
        super().__init__(n,pinA,pinB)
        
    def performGateLogic(self):
        # self.pinA = self.getPinA()
        # self.pinB = self.getPinB()
        if self.pinA == 1 or self.pinB == 1:
        # pinA = self.getPinA()
        # pinB = self.getPinB()
        # if pinA == 1 or pinB == 1:
            return 1
        else:
            return 0 
            
# 或非门
class NorGate(BinaryGate):
    
    def __init__(self,n,pinA=None, pinB=None):
        super().__init__(n,pinA,pinB)
    
    def performGateLogic(self):
        # self.pinA = self.getPinA()
        # self.pinB = self.getPinB()
        if self.pinA == 0 and self.pinB == 0:
            return 1
        else:
            return 0
    
 

            
# 异或门
class NorGate(BinaryGate):
    
    def __init__(self,n,pinA=None,pinB=None):
        super().__init__(n,pinA,pinB)
    
    def performGateLogic(self):
        # self.pinA = self.getPinA()
        # self.pinB = self.getPinB()
        if self.pinA == self.pinB:
            return 0
        else:
            return 1
            
# 非门
class NotGate(UnaryGate):
    def __init__(self,n,pin=None):
        super().__init__(n,pin)
        
    def performGateLogic(self):
        # self.pin = self.getPin()
        if self.pin==1:
            return 0
        else:
            return 1

class Connector():
    def __init__(self,fgate,tgate):
        self.fromgate = fgate
        self.togate = tgate
        
        tgate.setNextPin(fgate)
        
    def getFrom(self):
        return self.fromgate
     
    def getTo(self):
        return self.togate
        
class HalfAdder():
    
    def __init__(self,n,A,B):
        self.label = n
        self.A = A
        self.B = B
        self.S = NorGate("n1",A,B).output
        self.C = AndGate("n2",A,B).output
        
    def __str__(self):
        return "{} - A: {}; B: {}; S: {}; C: {}".format(self.label,self.A,self.B,self.S,self.C)
    
class Adder(): 

    def __init__(self,)

if __name__=="__main__":
    # g1 = AndGate("G1",0,1)
    # g2 = AndGate("G2",1,1)
    # g3 = OrGate("G3")
    # g4 = NotGate("G4")
    
    # c1 = Connector(g1,g3)
    # c2 = Connector(g2,g3)
    # c3 = Connector(g3,g4)
    # print(g1)
    # print(g2)
    # print(g3)
    # print(g4)
    # print(g4.output)
    h1 = HalfAdder("h1",0,0)
    h2 = HalfAdder("h2",0,1)
    h3 = HalfAdder("h3",1,0)
    h4 = HalfAdder("h4",1,1)
    print(h1)
    print(h2)
    print(h3)
    print(h4)   

你可能感兴趣的:(Python学习笔记)