C語言列出真分數序列程式碼及解析
問題描述
按遞增順序依次列出所有分母為60,分子小於60的最簡分數。
問題分析
分子、分母只有公因數1的分數叫做最簡分數或者說分子和分母是互質數的分數,叫做最簡分數,又稱既約分數,如2/3,8/9,3/8等。
方法一:
求分子小於60的最簡分數,對分子採用窮舉的方法。根據最簡分數定義知:分子分母的最大公約數為1,利用最大公約數的方法,判定分子與60是否構成真分數。
方法二:
分子、分母的公因數只有1的分數為最簡分數,若分子、分母在1〜分子(num2)(題目要求分子小於60,分子、分母的公約數小於兩者中的任意一個)之間除了1之外還有其他的公因數,則此分數肯定不是最簡分數。
演算法分析
變數num1、num2分別儲存分母、分子的值。
方法一:
求最大公約數一般採用輾轉相除的思想,具體步驟如下。 1. 用較大的數num1除以較小的數num2,得到的餘數儲存到變數temp中,temp=num1%num2。
2. 上一步中較小的除數num2和得出的餘數temp構成新的一對數,並分別賦值給num1和num2,繼續做上面的除法。
3. 當num2為0時,num1就是最大公約數,否則重複步驟 1、2。
方法二 :
分數的分子仍然採用窮舉法。對於每一個可能的分子,都要判斷在1〜num2範圍內,分數num1/num2除了1之外是否有其他的公因數,迴圈初值為2。
在2〜num2內若有一個數j能同時整除分子、分母,說明此分數不是最簡分數,j〜num2之間的數也無須再判斷,利用break語句結束迴圈。迴圈結束時j<num2。迴圈過程中若沒有一個數可以同時整除分子、分母即條件if(num1%j==0 && num2%j==0)不成立,則break語句不執行,迴圈正常結朿,即條件j<=num2不成立,迴圈結束時j>num2。利用j與num2的大小關係可判斷分數是否為最簡分數。
下面是方法一的完整程式:
#include<stdio.h>
int main()
{
int i, num1, num2, temp, n=0; /*n記錄最簡分數的個數*/
printf("分母是60的真分數有:\n");
for(i=1; i<60; i++) /*窮舉60以內的全部分子*/
{
num1 = 60;
num2 = i;
/*採用輾轉相除法求出最大公約數*/
while(num2 != 0)
{
temp = num1 % num2;
num1 = num2;
num2 = temp;
}
if(num1 == 1) /*若最大公約數為1,則為最簡真分數*/
{
n++;
printf("%2d/60 ", i);
if(n%8 == 0) /*每行輸出8個數*/
printf("\n");
}
}
return 0;
}
下面是方法二的完整程式碼:
#include<stdio.h>
int main()
{
int i, num1, num2, j, n=0; /*記錄最簡分數的個數*/
printf("The fraction serials with demominator 60 is:\n");
for(i=1; i<60;i++) /*窮舉60以內的全部分子*/
{
num1 = 60;
num2 = i;
for(j=2;j<=num2; j++)
/*判斷2~num2之間分子、分母是否有公約數,如果有j滿足條件,則結束迴圈,說明此時的分數不是最簡分數*/
if(num1%j==0 && num2%j==0)
break;
if(j>num2)
/*若j>num2說明2~num2之間沒有分子、分母的公約數,分數為最簡分數*/
{
printf("%2d/60", i);
n++;
if(n%8 == 0)
printf("\n");
}
}
return 0;
}
輸出結果:
分母是60的真分數有:
1/60 7/60 11/60 13/60 17/60 19/60 23/60 29/60
31/60 37/60 41/60 43/60 47/60 49/60 53/60 59/60