關於N個有理分數求和的分析(c語言)


題目要求

本題的要求很簡單,就是求N個數字的和。麻煩的是,這些數字是以有理數分子/分母的形式給出的,你輸出的和也必須是有理數的形式。

輸入格式:

輸入第一行給出一個正整數N≤100)。隨后一行按格式a1/b1 a2/b2 ...給出N個有理數。題目保證所有分子和分母都在長整型范圍內。另外,負數的符號一定出現在分子前面。

輸出格式:

輸出上述數字和的最簡形式 —— 即將結果寫成整數部分 分數部分,其中分數部分寫成分子/分母,要求分子小於分母,且它們沒有公因子。如果結果的整數部分為0,則只輸出分數部分。

輸入樣例1:

5 2/5 4/15 1/30 -2/60 8/3

輸出樣例1:

3 1/3
 

輸入樣例2:

2 4/3 2/3
 

輸出樣例2:

2
 

輸入樣例3:

3 1/3 -1/6 1/8
 

輸出樣例3:

7/24

編寫示例


下面讓我們看一段c語言代碼(無數組):
 1 #include<stdio.h>
 2 int GCD(int x,int y);
 3 int LCM(int x,int y);
 4 int main()
 5 {
 6     int n,x,y,i,a=0,b=0,m,t,k,f=0;
 7     scanf("%d\n",&n);
 8     for(i=1;i<=n;i++)
 9     {
10         x=a;//儲存兩個有理分數其中一個分子
11         y=b;//儲存x的分母
12         scanf("%d/%d",&a,&b);//輸入兩個整數,前者是分子,后者是分母
13         if(i==1)
14         {
15             continue;//第一次x,y沒有存儲到我們輸入的值,所以不能執行下面的代碼
16         }
17         t=LCM(b,y);//求出兩個有理分數中分母的最小公倍數(LCM)來進行分子的求和運算
18         a=(t/b)*a+(t/y)*x;//兩個有理分數求和后的一個新的有理分數的分子
19         b=t;//新有理分數中的分母// 
20     }
21     if(a>=b)//如果分子不小於分母,則則可以分離出一個整數部分k
22     {
23         k=a/b;
24         printf("%d",k);
25         a=a-k*b;//此時的a為有理化后的分數部分的分子
26         f=1;//作為a經過一次有理化之后的標志 
27     }
28     if(a==0&&f==1)
29     {
30         //如果a為0且f為1,則說明該有理分數求和時只得出了整數且該整數不為0
31     } 
32     else if(a==0&&f==0)
33     {
34         printf("0");//如果a為0且f為0,則說明有理分數求和時只得出了整數且該整數為0 
35     } 
36     else        /*除了上述兩個條件之外,無論是求和結果得出了整數和有理分數還是只得出了有理分數,
37     總之存在一個有理分數a/b(若f為1,則a是求和后分離出整數之后的新分子但我們為了簡便還用a表示;
38     若f為0,則a就是求和之后的分子)*/ 
39     {
40         m=GCD(a,b);
41         a/=m;
42         b/=m;
43         printf("%d/%d\n",a,b);
44     }
45     return 0;
46 }
47 int GCD(int x,int y)
48 {
49     int c;
50     c=x%y;
51     while(c!=0) 
52     {
53         x=y;
54         y=c;
55         c=x%y;
56     }
57     return y;
58 }
59 int LCM(int x,int y)
60 {
61     int temp, i;
62     if(x<y)
63     {
64         temp = x;
65         x= y;
66         y = temp;
67     }
68     for(i=x; i>0; i++)
69         if(i%x==0&&i%y==0)
70         {
71             return i;
72             break;
73         }
74 }

 

 

出現的問題

經過運行之后我們發現輸出結果與示例的結果均一致,但我們提交到做題系統后,卻只得了一半的分。(出現的問題)

 
               

解決方案


這是我們才發現系統判錯很公道,我們忘記了隨時化簡可能導致了數據溢出,而且我們忽略了輸出負整數和整數的情況。
通過進一步學習與調整,我們得出這套代碼:
 1  1 #include<stdio.h>
 2  2 #include<math.h>
 3  3 long int mygcd(long int a,long int b);
 4  4 void simplify(long int *up,long int *down,long int gcd);
 5  5 int main()
 6  6 {
 7  7     int N;
 8  8     scanf("%d",&N);
 9  9     long int up[N],down[N];     
10 10     for(int i=0;i<N;i++)    //輸入分子、分母 
11 11     {
12 12         scanf("%ld/%ld",&up[i],&down[i]);
13 13     }
14 14     long int gcd;
15 15     long int up1 = up[0]; 
16 16     long int down1 = down[0];    
17 17     simplify(&up1, &down1, mygcd(up1,down1));
18 18     for(int i=1; i<N;i++) 
19 19     {
20 20         if(up1!=0)    //前i-1項和不為0時 
21 21         {
22 22             long int temp;
23 23             simplify(&up1, &down1, mygcd(up1,down1));     //對前i-1項和進行化簡 
24 24             gcd = mygcd(down1,down[i]);        //求前i-1項和的分母與第i項分母的最大公約數 
25 25             temp = down1;
26 26             down1 = down1*down[i]/gcd;        //求前i-1項和的分母與第i項分母的最小公倍數
27 27             up1 *= down1/temp;        //分子分母同時放大 
28 28             up[i] *= down1/down[i];
29 29             up1 += up[i];
30 30         }
31 31         else        //前i-1項和為0 
32 32         {
33 33             down1 = down[i];
34 34             up1 = up[i];
35 35         }
36 36     }
37 37     simplify(&up1, &down1, mygcd(up1,down1));    //對最后一次計算結果進行化簡
38 38     if(up1==0)        //打印結果 
39 39     {
40 40         printf("0");
41 41     }
42 42     else if(up1/down1==0)
43 43     {
44 44         printf("%ld/%ld",up1,down1);
45 45     }
46 46     else if(up1%down1==0)
47 47     {
48 48         printf("%ld",up1/down1);
49 49     }
50 50     else
51 51     {
52 52         printf("%ld %ld/%ld",up1/down1,up1%down1,down1);
53 53     }
54 54     return 0;
55 55 }
56 56 
57 57 long int mygcd(long int a,long int b)    //計算最大公約數 
58 58 {
59 59     a = fabs(a);    //考慮a為負數 
60 60     long int r;
61 61     do
62 62     {
63 63         r = a%b;
64 64         a = b;
65 65         b = r;
66 66     }while(r!=0);
67 67     return a;
68 68 }
69 69 
70 70 void simplify(long int *up,long int *down,long int gcd)    //分數化簡 
71 71 {
72 72     *up /= gcd;
73 73     *down /= gcd;
74 74 }
75  

文末

感謝大家觀看本文,也希望大佬們多多指點。                                                                 2021-05-1701:05:28

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM