[英]Generating all factors of a number given its prime factorization
如果您已經對數字進行了素數分解,那么獲得該數字的所有因子的最簡單方法是什么? 我知道我可以從2循環到sqrt(n)並找到所有可分的數字,但這似乎效率低,因為我們已經有了素數分解。
我想它基本上是組合/選擇功能的修改版本,但我似乎找到的只是計算組合數量的方法,以及計算因子數量的方法,而不是實際生成組合/因子。
想象一下,主要的除數是一個桶中的球。 例如,如果您的數字的主要除數是2,2,2,3和7,那么您可以采用0,1,2或3個“球2”實例。 同樣,你可以把'球3'0或1次和'球7'0或1次。
現在,如果你把'球2'兩次和'球7'一次,你得到除數2 * 2 * 7 = 28.同樣,如果你沒有球,你得到除數1,如果你拿走所有球,你得到除數2 * 2 * 2 * 3 * 7等於數字本身。
最后,為了獲得可以從桶中獲取的所有可能的球組合,您可以輕松地使用遞歸。
void findFactors(int[] primeDivisors, int[] multiplicity, int currentDivisor, long currentResult) {
if (currentDivisor == primeDivisors.length) {
// no more balls
System.out.println(currentResult);
return;
}
// how many times will we take current divisor?
// we have to try all options
for (int i = 0; i <= multiplicity[currentDivisor]; ++i) {
findFactors(primeDivisors, multiplicity, currentDivisor + 1, currentResult);
currentResult *= primeDivisors[currentDivisor];
}
}
現在你可以在上面的例子中運行它:
findFactors(new int[] {2, 3, 7}, new int[] {3, 1, 1}, 0, 1);
dimo414,生成因子通常被認為是一項非常困難的任務。 事實上,保護您的大部分重要資產(即金錢,信息等),都依賴於簡單但極其困難的數字因素。 請參閱有關RSA加密方案的文章http://en.wikipedia.org/wiki/RSA_(cryptosystem) 。 我離題了。
為了回答你的問題,組合方法是你最好的方法,正如尼基塔所指出的那樣(順便說一下,你的解釋就是贊譽)。
我知道我可以從2循環到sqrt(n)並找到所有可分的數字
由於與生成素數相關的非常相似的概念,許多人跳到這個結論。 不幸的是,這是不正確的,因為你會錯過幾個不是素數的sqrt(n)因子(我會讓你自己證明這一點)。
現在,以確定的因素,對於任何給定數量的數n,我們期待為n的素因子。 如果n = p a ,那么我們知道n將具有( a + 1 )個因子( 1,p,p 2 ,...,p a )。 這是確定因素總數的關鍵。 如果n有多個素因子,比如說
N = P 1·P 2 B ...第Kr的
然后使用計數產品規則 ( http://en.wikipedia.org/wiki/Rule_of_product ),我們知道會有
m =( a + 1 ) · ( b + 1 ) ··· ( r + 1 )
因素。 現在,我們需要做的就是通過素數因子分解找到給我們的數字的每種可能組合。 下面是R中的一些代碼,希望能夠證明我所解釋的內容。
我的代碼的第一部分簡單檢查了素數,因為如果數字是素數,那么唯一的因素是1和它自己。 接下來,如果數字不是素數且大於1,我首先找到數字的素數因子化,比如我們有,
N = P 1·P 2 B ...第Kr的
然后我發現只有UniPrimes標記的唯一素數,因此對於這個例子,UniPrimes將包含( p 1 ,p 2 ,p k )。 然后我找到每個素數的所有冪並將其添加到一個標記為MyFactors的數組中。 在創建此數組之后,我會在MyFactors中找到元素的每個可能的產品組合。 最后,我向數組添加1(因為它是一個微不足道的因素),並對其進行排序。 瞧! 它非常快,適用於具有許多因素的非常大的數字。
我試圖使代碼盡可能地翻譯成其他語言(即我假設你已經構建了一個生成素數分解(或使用內置函數)和素數測試函數的函數。)我沒有'使用R獨有的專用內置函數。如果不清楚,請告訴我。 干杯!
factor2 <- function(MyN) {
CheckPrime <- isPrime(MyN)
if (CheckPrime == F && !(MyN == 1)) {
MyPrimes <- primeFactors(MyN)
MyFactors <- vector()
MyPowers <- vector()
UniPrimes <- unique(MyPrimes)
for (i in 1:length(UniPrimes)) {
TempSize <- length(which(MyPrimes == UniPrimes[i]))
for (j in 1:TempSize) {
temp <- UniPrimes[i]^j
MyPowers <- c(MyPowers, temp)
}
}
MyFactors <- c(MyFactors, MyPowers)
MyTemp <- MyPowers
MyTemp2 <- vector()
r <- 2
while (r <= length(UniPrimes)) {
i <- 1L
while (i <= length(MyTemp)) {
a <- which(MyPrimes > max(primeFactors(MyTemp[i])))
for (j in a) {
temp <- MyTemp[i]*MyPowers[j]
MyFactors <- c(MyFactors, temp)
MyTemp2 <- c(MyTemp2, temp)
}
i <- i + 1
}
MyTemp <- MyTemp2
MyTemp2 <- vector()
r <- r + 1
}
} else {
if (MyN == 1) {
MyFactors <- vector()
} else {
MyFactors <- MyN
}
}
MyFactors <- c(1, MyFactors)
sort(MyFactors)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.