1034 有理数四则运算(20)(20 分)
本题要求编写程序,计算2个有理数的和、差、积、商。
输入格式:
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。
输出格式:
分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。
输入样例1:
2/3 -4/2
输出样例1:
2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)
输入样例2:
5/3 0/6
输出样例2:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
问题分析:使用欧几里得算法 gcd() 计算公约数,函数 fmt() 格式化输出,fmt2() 对分数进行约分
程序:
def gcd(m,n):#欧几里得算法
m = abs(m)
n = abs(n)
if m<n:
m,n = n,m
while m%n!=0:
r = m%n
m = n
n = r
return n
def fmt(m,n):
if m=="Inf":
return m
if m<0 and n<0:
m = -m
n = -n
a = 0#整数部分
b = []#分数部分
str1 = ""
x = abs(m)
y = abs(n)
if x==0:
str1 = "0"
else:
a = x//y
b = [x-a*y,y]
if m<0 or n<0:
if a==0:
str1 = "(-"+str(b[0])+"/"+str(b[1])+")"
elif b[0]==0:
str1 = "(-"+str(a)+")"
else:
str1 = "(-"+str(a)+" "+str(b[0])+"/"+str(b[1])+")"
else:
if a==0:
str1 = str(b[0])+"/"+str(b[1])
elif b[0]==0:
str1 = str(a)
else:
str1 = str(a)+" "+str(b[0])+"/"+str(b[1])
return str1
def fmt2(b):
for i in b:
if i[0]==0:
i[0]=0
i[1]=1
else:
k = gcd(abs(i[0]),i[1])
if i[0]<0:
i[0] = -(abs(i[0])//k)
else:
i[0] = i[0]//k
i[1] = i[1]//k
a = input().split()
b = []
c = ['+','-','*','/']
for i in a:
b.append([int(j) for j in i.split('/')])
fmt2(b)
result = []
if b[1][0]!=0:
result.append([b[0][0]*b[1][1]+b[1][0]*b[0][1],b[0][1]*b[1][1]])
result.append([b[0][0]*b[1][1]-b[1][0]*b[0][1],b[0][1]*b[1][1]])
result.append([b[0][0]*b[1][0],b[0][1]*b[1][1]])
result.append([b[0][0]*b[1][1],b[0][1]*b[1][0]])
fmt2(result)
else:
result.append(b[0])
result.append(b[0])
result.append([0,0])
result.append(["Inf","Inf"])
for i in range(4):
print("%s %s %s %s %s"%(fmt(b[0][0],b[0][1]),c[i],fmt(b[1][0],b[1][1]),"=",fmt(result[i][0],result[i][1])))