数据结构的过程性表示:
习题2.5
:证明很容易,假设存在a<0或者b<0,则
Pair(a,b)=2a3|b|或者3b2|a|
因为gcd(2,3)=1,所以Pair(a,b)不能继续约分,所以Pair(a,b)不是整数。因此可以只用非负数来表示序对。
表示的代码如下:
def make_pair(a,b):
def dispatch(m):
if m==0:
return a
else:return b
return dispatch
def getitem_pair(p,i):
return p(i)
def make_integer(a,b):
return make_pair(a,b)
def get_a(n):
return n(0)
def get_b(n):
return n(1)
def mul(n1,n2):
a1,a2 = get_a(n1),get_a(n2)
b1,b2 = get_b(n1),get_b(n2)
return make_pair(a1+a2,b1+b2)
def div(n1,n2):
a1,a2 = get_a(n1),get_a(n2)
b1,b2 = get_b(n1),get_b(n2)
return make_pair(a1-a2,b1-b2)
def str_integer(n):
return '2^{0}*3^{1}'.format(get_a(n),get_b(n))
print(str_integer(mul(make_pair(3,2),make_pair(2,3))))
练习2.7−2.8:构造关于区间运算的体系:
def add_interval(a,b):
return make_interval(lower_bound(a)+lower_bound(b),upper_bound(a)+upper_bound(b))
def sub_inerval(a,b):
return make_interval(lower_bound(a)-upper_bound(b),upper_bound(a)-lower_bound(b))
def mul_interval(a,b):
l1,l2,u1,u2 = lower_bound(a),lower_bound(b),upper_bound(a),upper_bound(b)
p1,p2,p3,p4 = l1*l2,l1*u2,u1*l2,u1*u2
return make_interval(min([p1,p2,p3,p4]),max([p1,p2,p3,p4]))
def div_interval(a,b):
return mul_interval(a,make_interval(1/upper_bound(b),1/lower_bound(b)))
def make_interval(l,u):
return (l,u)
def lower_bound(m):
return getitem(m,0)
def upper_bound(m):
return getitem(m,1)
def str_interval(m):
return '[{0},{1}]'.format(lower_bound(m),upper_bound(m))
x,y = make_interval(-1,2),make_interval(4,6)
print(add_interval(x,y),mul_interval(x,y),div_interval(x,y),sub_inerval(x,y))
2.9证明(a) :关于区间宽度,对于加法和减法,组合区间的宽度是关于两个区间宽度的函数:
W(add(a,b))=W(a)+W(b)=W(sub(a,b))....(1)
举例子说明(b) :对于乘法和除法,则不满足函数关系:显然,当存在负数的时候,它可能满足几种关于两个宽度的关系式。如(-1,3),(4,6)
练习2.10,讨论除0错误 :
def div_interval(a,b):
assert(lower_bound(b)*upper_bound(b) > 0)
return mul_interval(a,make_interval(1/upper_bound(b),1/lower_bound(b)))
练习2.11,重写过程,根据断点情况进行分解:
思路就是一个区间有三种情况,然后3*3=9,当然写起来很是麻烦…..
def mul_interval(a,b):
def condition(l,u):
if l<0 and u<0:return 0
elif l*u <=0:return 1
return 2
l1,l2,u1,u2 = lower_bound(a),lower_bound(b),upper_bound(a),upper_bound(b)
index = condition(l1,u1)+condition(l2,u2)*3
if index == 0:return make_interval(u1*u2,l1*l2)
elif index==1:return make_interval(u1*l2,l1*l2)
elif index==2:return make_interval(u1*l1,l1*u2)
elif index==3:return make_interval(u2*l2,l2*u1)
elif index==4:return make_interval(min(l1*u2,l2*u1),max(l1*l2,u1*u2))#both span zero
elif index==5:return make_interval(u1*l2,u2*l2)
elif index==6:return make_interval(l1*u2,l2*u1)
elif index==7:return make_interval(l1*u2,u1*u2)
else:return make_interval(l1*l2,u1*u2)
练习2.12
def make_center_percent(a,b):
return (a,b)
def center(m):
return getitem(m,0)
def percent(m):
return getitem(m,1)
def error(m):
return center(m)*percent(m)/100
练习2.13
计算:X=[a−e1,a+e1],Y=[b−e2,b+e2]
X∗Y=[ab−a∗e2−b∗e1+e1∗e2,ab+a∗e2+b∗e1+e1∗e2]
e=a∗e2+be1,c=ab+e1∗e2==>
ec=a∗e2+b∗e1a∗b+e1∗e2=p1+p21+p1∗p2=p1+p2(while....p1,p2<<1)(p1=e1a,p2=e2b)