1、原题描述:
题目描述
本题要求编写程序,计算2个有理数的和、差、积、商。
输入描述:
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分
母不为0。
输出描述:
分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的
最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中
没有超过整型范围的整数。
输入例子:
5/3 0/6
输出例子:
1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf
2、思路
1)、本题属于模拟类问题,模拟类问题首先就要掌握题目的规则,然后对整体做出相应规划;本题中首先输入的分数其分子大于分母,也可以小于分母,分子可以为0,分母题目中保证不会为零,因此这种极端情况可以不用考虑;另外一点就是输入的分数不一定是最简化的,也就是还可以进行约分,我们需要将不管是输入的分数还是算的结果都要化成最简形式。
2)、可以定义一个约分打印函数,该函数可以解决:1.找到分子分母的最大公约数,2.针对输入的分子(绝对值)大于分母的情况,输出的结果需要考虑约分后并转化为带分数,负数要同时返回负号,因此可以在此做一个判断语句,另外一点,要考虑到约分后分母为1的情况,我们需要直接输出一个整数(本人经过在线测试发现,如果是负数需要带括号打印),为方便起见,1.约分打印函数返回值为可以直接打印的结果,不可以再处理;2.仅考虑分子不为零的情况。
3)、分别定义加、减、乘、除四个函数,降低代码重复利用率;
4)定义一个函数将两个输入的分数化为分母一致,以方便进行加、减运算。
5)、最后就是考虑所有情况的打印代码。
思路比较简单,但是代码比较冗长,因为需要考虑的边界情况比较多,需要多次调试才能具体确定(题目给的实在是比较模糊)
下面就给出自己的代码,并稍做解析:
# -*- coding: utf-8 -*-
"""
Created on Fri May 8 17:38:29 2020
@author: ScramJet
"""
input_n,input_m = input().split(' ')
n_a,n_b = map(eval,input_n.split('/'))#获取两个分数的分子分母
m_a,m_b = map(eval,input_m.split('/'))
def tongfen_func(n_a,n_b,m_a,m_b):#将两个分数分母化为一致方便加减运算,其中分子正负均可用。
n_anew = n_a*m_b
n_bnew = n_b*m_b
m_anew = m_a*n_b
m_bnew = m_b*n_b
return n_anew,n_bnew,m_anew,m_bnew
def yuefen_print_func(a,b): # 对一个分数的分母分子进行处理,得到题目所要求的结果,a为正为负均可使用
#首先找到分子分母的最大公约数,为方便只考虑分子为负,不考虑分母为负
s = 1
d = min(abs(a),b)
for k in range(1,d+1):
if a%k == 0 and b%k == 0:
s = k
#将分子分母同时除以最大公约数
a_n = a//s
b_n = b//s
if a_n > 0:#如果分子为正数
if b_n == 1:#分母为1,直接返回分子
return str(a_n)
if b_n != 1:
if a_n>b_n:#分子大于分母
return str(a_n//b_n)+' '+str(a_n%b_n)+'/'+str(b_n)#转化为带分数返回
if a_n<b_n:#分子小于分母
return str(a_n)+'/'+str(b_n)
if a_n < 0:
if b_n == 1:
return '('+'-'+str(abs(a_n))+')'#分子为负需要返回括号和负号
if b_n != 1:
if abs(a_n)>b_n:#带括号返回带分数
return '('+'-'+str(abs(a_n)//b_n)+' '+str(abs(a_n)%b_n)+'/'+str(b_n)+')'
if abs(a_n)<b_n:
return '('+'-'+str(abs(a_n))+'/'+str(b_n)+')'
def jiafa_func(n_a,n_b,m_a,m_b):#定义加法函数
if n_a != 0 and m_a != 0:
n_anew,n_bnew,m_anew,m_bnew = tongfen_func(n_a,n_b,m_a,m_b)#首先对两个分数通分
new1 = n_anew + m_anew#对分子相加
new2 = n_bnew
if new1 == 0:#结果为零直接返回零
return '0'
elif new1 != 0:#不为零则对新产生的和带入约分打印函数
return yuefen_print_func(new1,new2)
def jianfa_func(n_a,n_b,m_a,m_b):#减法同加法
if n_a != 0 and m_a != 0:
n_anew,n_bnew,m_anew,m_bnew = tongfen_func(n_a,n_b,m_a,m_b)
new1 = n_anew - m_anew
new2 = n_bnew
if new1 == 0:
return '0'
elif new1 != 0:
return yuefen_print_func(new1,new2)
def chengfa_func(n_a,n_b,m_a,m_b):
if n_a != 0 and m_a != 0:
new1 = n_a*m_a
new2 = n_b*m_b
return yuefen_print_func(new1,new2)
def chufa_func(n_a,n_b,m_a,m_b):#除法由于自身特点,需要对除数上下翻转在与被除数相乘,因此就会出现分母为负数的情况,而约分打印函数只考虑分子为负,为此需要讨论并等价转化为分母不为负
if n_a > 0 and m_a > 0:
new1 = n_a*m_b
new2 = n_b*m_a
if n_a > 0 and m_a < 0:
new1 = -n_a*m_b
new2 = -n_b*m_a
if n_a < 0 and m_a > 0:
new1 = n_a*m_b
new2 = n_b*m_a
if n_a < 0 and m_a < 0:
new1 = -n_a*m_b
new2 = -n_b*m_a
return yuefen_print_func(new1,new2)
#分子不为零的情况可以使用加、减、乘、除函数,按规则直接打印
if n_a != 0 and m_a != 0:
num_n = yuefen_print_func(n_a,n_b)
num_m = yuefen_print_func(m_a,m_b)
num_jia = jiafa_func(n_a,n_b,m_a,m_b)
num_jian = jianfa_func(n_a,n_b,m_a,m_b)
num_cheng = chengfa_func(n_a,n_b,m_a,m_b)
num_chu = chufa_func(n_a,n_b,m_a,m_b)
print('{} + {} = {}'.format(num_n,num_m,num_jia))
print('{} - {} = {}'.format(num_n,num_m,num_jian))
print('{} * {} = {}'.format(num_n,num_m,num_cheng))
print('{} / {} = {}'.format(num_n,num_m,num_chu))
#分子为零的情况不需要使用加减乘除函数,比较简单,直接打印即可
if n_a == 0 and m_a != 0:
num_n = 0
num_m = yuefen_print_func(m_a,m_b)
print('{} + {} = {}'.format(num_n,num_m,num_m))
print('{} - {} = {}{}{}'.format(num_n,num_m,'(','-'+num_m,')'))
print('{} * {} = {}'.format(num_n,num_m,'0'))
print('{} / {} = {}'.format(num_n,num_m,'0'))
if n_a != 0 and m_a == 0:
num_n = yuefen_print_func(n_a,n_b)
num_m = 0
print('{} + {} = {}'.format(num_n,num_m,num_n))
print('{} - {} = {}'.format(num_n,num_m,num_n))
print('{} * {} = {}'.format(num_n,num_m,'0'))
print('{} / {} = {}'.format(num_n,num_m,'Inf'))
代码线上测评AC,但总觉得还是有边界条件没有考虑完全,欢迎评论交流讨论,谢谢!