1. 程式人生 > >小數化分數解題報告---模擬

小數化分數解題報告---模擬

Q - 小數化分數2

Description

Ray 在數學課上聽老師說,任何小數都能表示成分數的形式,他開始了化了起來,很快他就完成了,但他又想到一個問題,如何把一個迴圈小數化成分數呢? 
請你寫一個程式不但可以將普通小數化成最簡分數,也可以把迴圈小數化成最簡分數。 

Input

第一行是一個整數N,表示有多少組資料。 
每組資料只有一個純小數,也就是整數部分為0。小數的位數不超過9位,迴圈部分用()括起來。 

Output

對每一個對應的小數化成最簡分數後輸出,佔一行。

Sample Input

3

0.(4)

0.5

0.32(692307)

Sample Output

4/9

1/2

17/52

解題思路:

根據題目可知,一共有三種形式的小數需要我們去轉換成分數,分別為:
  • 有限小數:形如 0.2,0.33
  • 純迴圈小數:形如 0.333333333…
  • 非純迴圈小數:形如 0.32477777… ,0.24367676767…

    顯然,無限不迴圈小數不可能轉換為分數(中學知識),而對於上面兩種迴圈小數,我們不妨分情況來討論。

    1、純迴圈小數 
    0.33333… * 10 = 3.33333… 
    (10 - 1) * 0.33333… = 3 
    即 9 * 0.33333… = 3 
    所以 0.33333… = 3/9 = 1/3 
    再舉一個例子 
    0.474747… * 100 = 47.474747… 
    (100 - 1) * 0.474747… = 47 
    即 99 * 0.474747… = 47 
    所以 0.474747… = 47/99

    由上述兩個例子我們可以發現,純迴圈小數化成分數過後其分子就為所迴圈單元化成的數,分母則全由9組成,位數和迴圈數的位數相同。

    2、非純迴圈小數 
    0.4777777… * 10 = 4.7777… 
    0.477777… * 100 = 47.77777… 
    (100 - 10) * 0.4777777… = 43 
    所以 0.4777777… = 43/90 
    再舉一個例子 
    0.323565656… * 1000 = 323.56565656… 
    0.323565656… * 100000= 32356.565656… 
    (10000 - 1000) * 0.32356565656… = 32033 
    所以 0.32356565656… = 32033/99000

    由上述兩個例子我們可以發現,非純迴圈小數化成分數過後其分子為 非迴圈部分與第一個迴圈部分 組成的數減去非迴圈部分的數,分母則為9與0組成的數,9的位數和迴圈部分數的位數相同,0的位數則和非迴圈部分數的位數相同

    PS:對於有限小數,不妨看作是非純迴圈小數的一種特例子,即0.3 = 0.30000000

原始碼如下:

#include <cstdio>
#include <math.h>
int gcd(int a,int b){
    int c;
    c = a % b;
    while (c) {
        a = b;
        b = c;
        c = a % b;
    }
    return b;
}

int main(){
    int N;
    scanf("%d",&N);
    while (N--) {
        char a[15];
        scanf("%s",a);
        int flag1 = 0;              //用來判斷是否檢查到過 '(' 符號
        int p = 0,q = 0;            //p代表非迴圈的位數,q代表迴圈的位數
        int x = 0,y = 0,z = 0;      //x代表分子,y代表分母,z代表括號中的數

        for (int i = 2;a[i];i++){
            if (a[i] != '(' && flag1 == 0){
                x *= 10;
                x += a[i] - '0';
                p++;
            }

            if (a[i] == '(' && flag1 == 0){
                flag1 = 1;
                i++;
            }

            if (a[i] != ')' && flag1 == 1){
                z *= 10;
                z += a[i] - '0';
                q++;
            }


        }

        if (flag1 && p){
            int n = q;
            int m = p;
            int temp = x;
            while(n--){
                y *= 10;
                y += 9;
                x *= 10;
            }
            while(m--){
                y *= 10;
            }
            x = x + z - temp;
        }
        if (flag1 && !p ){
            int n = q - 1;
            y = 9;
            x = z;
            while (n--) {
                y *= 10;
                y += 9;
            }
        }
        if (!flag1){
            int n = p;
            y = 1;
            while(n--)
                y *= 10;
        }

        int c = gcd(x, y);
        x /= c;
        y /= c;
        printf("%d/%d\n",x,y);
    }
    return 0;
}