簡體   English   中英

按升序打印一個數字的所有唯一素因數

[英]Print all unique prime factors of a number in ascending order

我是一個初學者並且完全困惑,我需要顯示一個數字的所有主要除數,但是在第一個代碼中計算需要很長時間,在第二個代碼中,如果我輸入數字 2,那么 java 打印 1 和2.但我只需要2。

例子:

input 360
output 2 3 5

input 2
output 2

input 999999797
output 999999797

如果我輸入 999999797 那么“時間限制”我的錯誤是什么?

for (d = 2; x > 1; d++) {
    if (x % d == 0) {
        x = x / d;
        for (int i = 0; x % d == 0; i++) {
            x = x / d;
        }
        System.out.println(d);
    }
}

 for (d = 2; x % d == 0; d++) {
     for (int i = 0; x % d == 0; i++) {
        x = x / d;
     }
     System.out.println(d);
 }
 System.out.println(x);

清理第一個片段的代碼(實際上很好)將是:

    int d = 2;
    int step = 1;
    while (x > 1) {
        if (x % d == 0) {
            System.out.println(d);
            x /= d;
            while (x % d == 0) {
                x /= d;
            }
        }
        d += step;
        step = 2;
    }

我添加了一個小優化,只測試了 2、3、5、7、9 等,以證明不需要測試許多除數。 一半的候選人。

推廣到跳過 2、3、5:

對於模 2 * 3 * 5 的數字:

// Unneeded code:
boolean[] dividable = new int[2*3*5]; // non-candidates to be skipped.
for (int i = 0; i < dividable.length; ++i) {
    dividable[i] = i % 2 == 0 || i % 3 == 0 || i % 5 == 0;
}
// cycle length: 2*3*5 == 30.
// result: tfttt ttftt tftft ttftf tttft ttttf
// steps:   2      7   11 13  17 19  23     29 (8 from 30 candidates, a fourth)

然后可以進一步優化代碼(雖然更丑陋):

final int cycleLength = 2*3*5;
final int[] initialSteps = {  2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
final int[] nextSteps =    {1,         7, 11, 13, 17, 19, 23, 29};
int[] steps = initialSteps;
for (int b = 0; x > 1; b += cycleLength) {
    for (int i = 0; x > 1 && i < steps.length; ++i) {
        int d = b + steps[i];
        while (x > 1) {
            if (x % d == 0) {
                System.out.println(d);
                x /= d;
                while (x % d == 0) {
                    x /= d;
                }
            }
        }
    }
    steps = nextSteps;
}

快了不到五倍。 (未經測試的代碼。)

對於那些對數學感興趣的人:注意這些steps當然是素數,並且初始步驟的initialSteps應該包含(i % P == 0 && i / P == 1)


沒有 arrays,使用位代替

由於其中一項要求似乎是避免 arrays (盡管在這里它們的長度是固定的),因此可以使用位。 對於 30 位,一個 int 就足夠了。

final int cycleLength = 2*3*5;
final int common = 1<<7 | 1<<11 | 1<<13 | 1<<17
       | 1<<19 | 1<<23 | 1<<29;
final int initialSteps = 1<<2 | 1<<3 | 1<<5 | common;
final int nextSteps =   1<<1 | common;
long steps = initialSteps;
for (int b = 0; x > 1; b += cycleLength) {
    for (int i = 0, int mask = 1; x > 1 && i < cycleLength; ++i, mask <<= 1) {
        if ((steps & mask) != 0) {
            int d = b + i;
            while (x > 1) {
                if (x % d == 0) {
                    System.out.println(d);
                    x /= d;
                    while (x % d == 0) {
                        x /= d;
                    }
                }
            }
        }
    }
    steps = nextSteps;
}

請注意,這更難看,我不確定代碼是否正確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM