[英]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.