(PAT乙级)有理数四则运算问题思路与解析

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,但总觉得还是有边界条件没有考虑完全,欢迎评论交流讨论,谢谢!

猜你喜欢

转载自blog.csdn.net/weixin_46047216/article/details/106000299
今日推荐