计算机科学研究的是能逐步解决问题的算法,算法就是一个解决方案。
抽象数据类型从逻辑上分析数据和其运算而不考虑具体的实现过程,数据结构是抽象数据类型的实现。
python面型对象编程
面向对象编程的python允许用户创建类来对解决问题需要的数据进行建模,通过创建类,我们可以很快捷的创建一系列需要的对象。类对象包含属性和方法,属性是类的特征,而方法则是解决问题的过程,比如说我们创建了一个人的类,那性别、身高、名字等特征就是属性,而唱、跳、rap就可以看成是方法。在创建类的时候,要先声明类,并进行初始化对象。
类提供了一系列默认方法供用户使用,不过用户也可以重写这些方法来满足更丰富的使用需要。要构造方法,总是将方法命名为__init__,需要注意的是,不要直接调用__init__。
class 类名:
课后练习:
1-9主要是创建一个表示分数的类,并逐步完善。 在创建类的时候,要先初始化对象,同时我们需要引入两个参数,其中top用来表示分子,botton表示分母,同时要注意分数形式中不能出现小数。
class Fraction:
#初始化
def __init__(self,top,botton):
if int(top) != float(top) or int(botton) != float(botton):
raise RuntimeError("你不能使用小数")
self.top = top
self.botton = botton
创建两个方法分别用来返回分子和分母,同时,重写 str 方法用来表达分数。python本身不提供分数的表达形式,因此我们要自己构建一个拼接字符串,涉及到数字的部分要注意将其格式化为字符串。这里的common是一个最大公因数,用来最简化分数。
def __str__(self):
common = self.gcd(self.top,self.botton)
return str(self.top//common) + "/" + str(self.botton//common)
def getNum(self):
return self.top
# 返回分母
def getDem(self):
return self.botton
我们需要一个用来计算最大公因数的算法,如果分子除分母余数为0,那么分母就是最大公因数,否则,我们就把分母作为分子,余数做分母继续计算,直到余数取0为止。
#最大公因私
def gcd(self,m,n):
while m % n != 0:
oldm = m
oldn = n
m = oldn
n = oldm % oldn
return n
在这个题目中,我们还要重写四则运算的规则,other代表另一个分数,同时不要忘记调用最大公因数来简化结果。在计算加减法的过程中,我们要给两个分数寻找一个共同的分母,因此我们的思路是分母相乘,分子分母交叉相乘。乘法直接相乘即可,而在计算除法的过程中,最好的方法是用一个分数乘另一个分数的倒数。
#最简加法
def __add__(self, other):
newtop = self.top*other.botton + self.botton*other.top
newbotton = self.botton * other.botton
common = self.gcd(newtop,newbotton)
return Fraction(newtop//common,newbotton//common)
#减法运算
def __sub__(self, other):
newtop = self.top*other.botton - self.botton*other.top
newbotton = self.botton * other.botton
common = self.gcd(newtop,newbotton)
return Fraction(newtop//common,newbotton//common)
# 乘法运算
def __mul__(self, other):
newtop = self.top * other.top
newbotton = self.botton * other.botton
common = self.gcd(newtop, newbotton)
return Fraction(newtop // common, newbotton // common)
# 除法运算
def __truediv__(self, other):
newtop = self.top * other.botton
newbotton = self.botton * other.top
common = self.gcd(newtop, newbotton)
return Fraction(newtop // common, newbotton // common)
第四题的内容对应的是两个分数的一系列大小比较,我们的思路是寻找共同的分母,比较分子,因此直接比较分子乘分母的大小,需要注意的是区分正负号。
# 判断原本的参数是否大于新的参数
def __gt__(self,other):
if self.top * other.botton * self.botton * other.botton >= 0:
if self.top * other.botton > self.botton * other.botton:
return True
else:
return False
else:
if self.top * self.botton > 0:
return True
else:
return False
def __ge__(self,other):
if self.top * other.botton * self.botton * other.botton >= 0:
if self.top * other.botton > self.botton * other.botton:
return True
else:
return False
else:
if self.top * self.botton > 0:
return True
else:
return False
def __lt__(self,other):
if self.top * other.botton * self.botton * other.botton >= 0:
if self.top * other.botton < self.botton * other.botton:
return True
else:
return False
else:
if self.top * self.botton < 0:
return True
else:
return False
def __le__(self,other):
if self.top * other.botton * self.botton * other.botton >= 0:
if self.top * other.botton <= self.botton * other.botton:
return True
else:
return False
else:
if self.top * self.botton <= 0:
return True
else:
return False
# 不等式判别
def __ne__(self,other):
if self.top * other.botton != self.botton * other.botton:
return True
else:
return False
__radd__
是 Python 中的一个特殊方法(也称为魔术方法),用于实现右侧加法运算的行为。
__iadd__
方法定义在类中,用于实现对象的原地加法运算(in-
zplace addition)。我们可以将它看成是在__add__
的基础上将原有的分数改成新的分数。- __repr__
方法应该返回一个字符串,该字符串是一个有效的Python表达式,通过使用该字符串可以重新创建该对象。
def __radd__(self, other):
newtop = self.top*other.botton +self.botton*other.top
newbotton = self.botton*other.botton
return Fraction(newtop,newbotton)
def __iadd__(self, other):
newtop = self.top * other.botton + self.botton * other.top
newbotton = self.botton * other.botton
self.top = newtop
self.botton = newbotton
def __repr__(self):
return "这是分数"
第10题要求我们构造一个与门,我们考虑的问题包括输入的来源、输入的内容、输出的内容、结果的条件判断。与门需要两个输入,当逻辑来源不存在时,用None表示, self.pin = [None,None]表示有两个输入,self.name表示逻辑门的名字,方便我们在使用时加以区分, self.output代表输出结果。 setPin用来表示接口,我们有0,1两个接口pin_num,用来表示我们使用的接口,source表述输入。 getPin用来取得输入的值,如果值为None,我们就手动输入一个值。performGateLogic是一个逻辑判断,在这里我们输入两个值并判断结果,只用两个值皆为1时,该逻辑门返回1。def getOutput(self)用来返回结果。
与门(AND gate)是一种逻辑门电路,它接收两个输入信号并产生一个输出信号。只有当两个输入信号同时为逻辑高(1)时,输出信号才为逻辑高;否则,输出信号为逻辑低(0)。
#与门
class AndGate1:
# 初始化,包含逻辑门的名字、输入、输出
def __init__(self,name):
self.name = name
self.pin = [None,None]
self.output = None
# 接口,数据来源
def setPin(self,source,pin_num):
self.pin[pin_num] = source
# 如果逻辑值存在就输出,否则手动输入
def getPin(self,pin):
if pin == None:
return input("输入逻辑"+self.name)
else:
return self.getOutput()
def performGateLogic(self):
# 利用逻辑门输入判断结果
self.pin[0] = self.getPin(self.pin[0])
self.pin[1] = self.getPin(self.pin[1])
if self.pin[0] == 1 and self.pin[1] == 1:
return 1
else:
return 0
# 输出
def getOutput(self):
self.output = self.performGateLogic()
return self.output
或门(OR gate)是一种逻辑门电路,它接收两个输入信号并产生一个输出信号。只要两个输入信号中至少有一个为逻辑高(1),输出信号就为逻辑高;只有当两个输入信号同时为逻辑低(0)时,输出信号才为逻辑低。
class OrGate1:
def __init__(self,name):
self.name = name
self.pin = [None,None]
self.output = None
def setpin(self,source,pin_num):
self.pin[pin_num] = source
def getpin(self,pin):
if pin == None:
return int(input("输入逻辑"+self.name))
else:
return self.getoutput()
def performGateLogic(self):
self.pin[0] = self.getpin(self.pin[0])
self.pin[1] = self.getpin(self.pin[1])
if self.pin[0] == 1 or self.pin[1] == 1:
return 1
else:
return 0
def getoutput(self):
self.output = self.performGateLogic()
return self.output
非门(NOT gate),也称为反相器,是一种逻辑门电路,它接收一个输入信号并产生一个输出信号。非门的输出信号与输入信号相反,当输入信号为逻辑高(1)时,输出信号为逻辑低(0);当输入信号为逻辑低(0)时,输出信号为逻辑高。
class NOT:
def __init__(self,name):
self.name = name
self.pin = None
self.outpin = None
def setpin(self,source):
self.pin = source
def getpin(self,pin):
if pin == None:
return int(input("输入逻辑"+self.name))
else:
return self.output()
def performGateLogic(self):
self.pin = self.getpin(self.pin)
if self.pin == 1:
return 0
else:
return 1
def output(self):
self.outpin = self.performGateLogic()
return self.outpin
异或门(XOR gate)是一种逻辑门电路,它接收两个输入信号并产生一个输出信号。异或门的输出信号在两个输入信号不相等时为逻辑高(1),在两个输入信号相等时为逻辑低(0)。
class XOR_gate:
def __init__(self,name):
self.name = name
self.pin = [None,None]
self.output = None
def setpin(self,source,pin_num):
self.pin[pin_num] = source
def getpin(self,pin):
if pin == None:
return int(input("输入逻辑"+self.name))
else:
return self.getoutput()
def performGateLogic(self):
self.pin[0] = self.getpin(self.pin[0])
self.pin[1] = self.getpin(self.pin[1])
if self.pin[0] == self.pin[1]:
return 0
else:
return 1
def getoutput(self):
self.output = self.performGateLogic()
return self.output
半加器(Half Adder)是一种组合逻辑电路,用于对两个输入位进行加法运算,并产生两个输出位:和位(Sum)和进位位(Carry)。
class XOR_gate:
def __init__(self,a,b):
self.a = a
self.b = b
self.sum()
self.carrybit()
def sum(self):
if self.a == self.b:
print("s=0")
else:
print("s=1")
def carrybit(self):
if self.a == 1 and self.b == 1:
print("c=1")
else:
print("C=0")
用一个简单的逻辑电路表示半加器:
class AndGate2:
def cal(self,a,b):
self.pin = [a,b]
if self.pin[0] == 1 and self.pin[1] == 1:
return 1
else:
return 0
class OrGate2:
def cal(self,a,b):
self.pin = [a, b]
if self.pin[0] == 1 or self.pin[1] == 1:
return 1
else:
return 0
class NoGate2:
def cal(self,a):
self.pin = a
if self.pin == 1 :
return 0
else:
return 1
g1 = AndGate2()
g2 = OrGate2()
g3 = NoGate2()
# 半加器
carry = g1.cal(1,1)
print(carry)
sum = g2.cal(g1.cal(1,1),g3.cal(g1.cal(1,1)))
print(sum)
全加器(Full Adder)是一种组合逻辑电路,用于对三个输入位进行加法运算,并产生两个输出位:和位(Sum)和进位位(Carry)。
class Full_Adder:
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
self.sum()
self.carrybit()
def sum(self):
if self.a == self.b:
if self.c == 0:
print("s=0")
else:
print("s=1")
else:
if self.c == 1:
print("s=0")
else:
print("s=1")
def carrybit(self):
if self.a == self.b :
print("c=1")
else:
print("C=0")