zoukankan      html  css  js  c++  java
  • PAT乙级1034-----有理数四则运算 (20分)(错)

    1034 有理数四则运算 (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

    思路1:

    1.将输入的分数分成 整数 分子 分母 符号 并将分子分母通分

    2.根据符号确定输出格式即为负要加()和负号

    3.判断分母是否为1决定是否只有整数

    4.判断整数是否为0决定是否加入整数


    首次代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 
     4 //辗转相除法求两个数的最大公因数
     5 long long hcf(long long a,long long b){
     6     long long r=a%b;
     7     while(r!=0){
     8         a=b;
     9         b=r;
    10         r=a%b;
    11 }
    12 return b>1?b:1;
    13 }
    14 //输出分数
    15 void input(long long k1,long long a1,long long a2,int flag){
    16        //符号为负
    17         if(flag){
    18           if(k1==0) printf("(-%lld/%lld)",a1,a2);
    19           else {
    20               if(a2==1) printf("(-%lld)",k1);
    21               else printf("(-%lld %lld/%lld)",k1,a1,a2);
    22           }
    23         }
    24         else {
    25             if(a1==0) printf("0");
    26             else if(a2==1) printf("%lld",k1);
    27             else if(k1!=0) printf("%lld %lld/%lld",k1,a1,a2);
    28             else printf("%lld/%lld",a1,a2);
    29         }
    30 }
    31 int main(){
    32     long long f1,f2,g1,g2;//输入的分子分母
    33     int flag1=0,flag2=0;//进行运算的两个数的符号 0为正 1为负
    34     scanf("%lld/%lld %lld/%lld",&f1,&f2,&g1,&g2);
    35     if(f1<0) flag1=1;
    36     if(g1<0) flag2=1;
    37     long long k1=0,k2=0;//整数部分
    38     long long a1=abs(f1),a2=f2,b1=abs(g1),b2=g2;//a1 b1为分子 a2 b2为分母
    39     long long h1=hcf(a1,a2);//a1 a2最大公因数
    40     long long h2=hcf(b1,b2);//b1 b2最大公因数
    41     a1/=h1;a2/=h1;b1/=h2;b2/=h2;//上下通分
    42     k1=a1/a2;//提出整数部分
    43     k2=b1/b2;
    44     a1=a1%a2;//分子化为最简
    45     b1=b1%b2;//分子化为最简
    46     for(int i=0;i<4;i++){
    47         input(k1,a1,a2,flag1);
    48         //输出运算符号
    49         switch(i){
    50             case 0:printf(" + ");break;
    51             case 1:printf(" - ");break;
    52             case 2:printf(" * ");break;
    53             case 3:printf(" / ");break;
    54         }
    55         input(k2,b1,b2,flag2);
    56         printf(" = ");
    57         switch(i){
    58             //加法
    59             case 0:{long long c1=f1*g2+f2*g1;long long c2=f2*g2;//用初始的分子分母通分进行计算
    60                     int flag3=0;if(c1<0) flag3=1;c1=abs(c1);
    61                     long long h3=hcf(c1,c2);c1/=h3;c2/=h3;long long k3=c1/c2;c1=c1%c2;
    62                     input(k3,c1,c2,flag3);printf("
    ");break;}
    63             //减法
    64             case 1:{long long c1=f1*g2-f2*g1;long long c2=f2*g2;
    65                     int flag3=0;if(c1<0) flag3=1;c1=abs(c1);
    66                     long long h3=hcf(c1,c2);c1/=h3;c2/=h3;long long k3=c1/c2;c1=c1%c2;
    67                     input(k3,c1,c2,flag3);printf("
    ");break;}
    68             //乘法
    69             case 2:{long long c1=f1*g1;long long c2=f2*g2;
    70                     int flag3=0;if(c1<0) flag3=1;c1=abs(c1);
    71                     long long h3=hcf(c1,c2);c1/=h3;c2/=h3;long long k3=c1/c2;c1=c1%c2;
    72                     input(k3,c1,c2,flag3);printf("
    "); break;}
    73             //除法
    74             case 3:{long long c1=f1*g2;long long c2=f2*g1;
    75                     if(!c2) {printf("Inf");break;}
    76                     int flag3=0;if((c1<0&&c2>0)||(c1>0&&c2<0)) flag3=1;c1=abs(c1);c2=abs(c2);
    77                     long long h3=hcf(c1,c2);c1/=h3;c2/=h3;long long k3=c1/c2;c1=c1%c2;
    78                     input(k3,c1,c2,flag3);break;}
    79         }
    80     }
    81     return 0;
    82 }
    83 
    84 //错误1:忘记把分子化为最简
    View Code

    想了很久找不到哪里出错了

    只能去参考别人的代码进行改进

    参考的代码:

     1 #include <stdio.h>
     2 long gcd(long a,long b){//辗转相除法求最大公约数
     3     long r=a%b;
     4     while(r!=0){
     5         a=b;
     6         b=r;
     7         r=a%b;
     8     }
     9     return b;
    10 }
    11 long func(long a,long b){
    12     if(b==0){
    13         printf("Inf");
    14         return 0;
    15     }
    16     int sam=1;
    17     if(a<0){
    18         a=-a;
    19         sam=sam*(-1);
    20     }
    21     if(b<0){
    22         b=-b;
    23         sam=sam*(-1);
    24     }
    25     //约分为最简分数
    26     long r=gcd(a,b);
    27     a=a/r;
    28     b=b/r;
    29     if(sam==-1){
    30         printf("(-");
    31     }
    32     if(b==1){
    33         printf("%ld",a);
    34     }else if(a<b){
    35         printf("%ld/%ld",a,b);
    36     }else if(a>b){
    37         printf("%ld %ld/%ld",a/b,a%b,b);
    38     }
    39     if(sam==-1){
    40         printf(")");
    41     }
    42     return 0;
    43 }
    44 int main(){
    45     long c,d,e,f;
    46     scanf("%ld/%ld %ld/%ld",&c,&d,&e,&f);
    47     //加法
    48     func(c,d);
    49     printf(" + ");
    50     func(e,f);
    51     printf(" = ");
    52     func(c*f+e*d,d*f);
    53     printf("
    ");
    54     //减法
    55     func(c,d);
    56     printf(" - ");
    57     func(e,f);
    58     printf(" = ");
    59     func(c*f-e*d,d*f);
    60     printf("
    ");
    61     //乘法
    62     func(c,d);
    63     printf(" * ");
    64     func(e,f);
    65     printf(" = ");
    66     func(c*e,d*f);
    67     printf("
    ");
    68     //除法
    69     func(c,d);
    70     printf(" / ");
    71     func(e,f);
    72     printf(" = ");
    73     func(c*f,d*e);
    74     return 0;
    75 }
    View Code

    FROM:https://www.cnblogs.com/gh110/p/12158217.html

    改进后的代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 
     4 //辗转相除法求两个数的最大公因数
     5 long long hcf(long long a,long long b){
     6     long long r=a%b;
     7     while(r!=0){
     8         a=b;
     9         b=r;
    10         r=a%b;
    11 }
    12 return b>1?b:1;
    13 }
    14 //输出分数
    15 long func(long a,long b){
    16     if(b==0){
    17         printf("Inf");
    18         return 0;
    19     }
    20     int sam=1;
    21     if(a<0){
    22         a=-a;
    23         sam=sam*(-1);
    24     }
    25     if(b<0){
    26         b=-b;
    27         sam=sam*(-1);
    28     }
    29     //约分为最简分数
    30     long r=hcf(a,b);
    31     a=a/r;
    32     b=b/r;
    33     if(sam==-1){
    34         printf("(-");
    35     }
    36     if(b==1){
    37         printf("%ld",a);
    38     }else if(a<b){
    39         printf("%ld/%ld",a,b);
    40     }else if(a>b){
    41         printf("%ld %ld/%ld",a/b,a%b,b);
    42     }
    43     if(sam==-1){
    44         printf(")");
    45     }
    46     return 0;
    47 }
    48 int main(){
    49     long long f1,f2,g1,g2;//输入的分子分母
    50     scanf("%lld/%lld %lld/%lld",&f1,&f2,&g1,&g2);
    51     for(int i=0;i<4;i++){
    52         func(f1,f2);
    53         //输出运算符号
    54         switch(i){
    55             case 0:printf(" + ");break;
    56             case 1:printf(" - ");break;
    57             case 2:printf(" * ");break;
    58             case 3:printf(" / ");break;
    59         }
    60         func(g1,g2);
    61         printf(" = ");
    62         switch(i){
    63             //加法
    64             case 0:{long long c1=f1*g2+f2*g1;long long c2=f2*g2;//用初始的分子分母通分进行计算
    65                     func(c1,c2);printf("
    ");
    66                     break;}
    67             //减法
    68             case 1:{long long c1=f1*g2-f2*g1;long long c2=f2*g2;
    69                     func(c1,c2);printf("
    ");break;}
    70             //乘法
    71             case 2:{long long c1=f1*g1;long long c2=f2*g2;
    72                     func(c1,c2);printf("
    "); break;}
    73             //除法
    74             case 3:{long long c1=f1*g2;long long c2=f2*g1;
    75                     func(c1,c2);break;}
    76         }
    77     }
    78     return 0;
    79 }
    View Code

    换用成func函数后通过

    改进后的思路(func函数):

    1. 首先判断分母是否为0决定输出Inf——此情况只有在除法才可能发生,因为除法交换除数的分子分母,而题设输入的分母不会为0
    2. 根据输入的分子a,分母b的符号判断最终的符号
    3. 根据分子分母的大小比较决定输出的结果

    错误总结:

    1. 逻辑错误:input函数中的某种情况我可能没有考虑到
    2. 代码过于复杂不够简洁精炼导致后续检查花费时间太多
  • 相关阅读:
    宝宝打疫苗
    【小工具】2. 需要对测试用的数据进行MD5加密
    【小工具】1.需要对txt存放的测试数据做去重处理
    【Jenkins】定时构建语法
    【bug】记一个有趣的“bug”
    1.由于测试某个功能,需要生成500W条数据的txt,python代码如下
    开发基于vue前端框架下的系统的UI自动化,记录总结踩的坑
    使用Chrome-headless模式下,截屏不全屏的问题
    Chrome-headless 模式,没有UI界面的自动化UI测试
    【selenium】Webdriver的原理以及工作流程
  • 原文地址:https://www.cnblogs.com/a982961222/p/12357426.html
Copyright © 2011-2022 走看看