2009-07-07 57 views
5

給出數字的所有素數因子以及它們的多重性(最高冪次)。
需求是產生該數字的所有因素。獲取數字的所有因子(迭代器攤牌:)

我舉一個例子:

總理因素:

  • 2(功率:3)
  • 3(功率:1)

(意味着數爲2^3 * 3^1 = 24

預期的結果是:
1,2,3,4,6,8,12,24

我想這樣做(在C#中)與一些鏈式自定義迭代器,每個素數因子,將從0計數到該素數的權力。

你將如何實現這一點?使用您的首選語言。

這是從Project Euler

+2

我不知道這個項目歐拉管理員如何愛是SO暴露解決他們的問題。請參閱http://stackoverflow.com/questions/1010739/help-with-project-euler-200-closed。 – anderstornvig 2009-07-07 10:03:00

+3

在這種情況下,我認爲它是可以的,因爲問題要求標準算法,而不是問題的解決方案。此外,問題仍然很容易,這不是最好的方法。 – starblue 2009-07-07 10:56:00

+1

+1,這完全不是歐拉項目問題。這個問題是一個非常普遍的問題,當然是一個「真正的」編程問題。 (指兩個投票結果爲「不是真正的問題」。) – ShreevatsaR 2009-07-07 19:12:36

回答

3

考慮所有可能的權力組合。對於每個組合,將素數提高到相應的功率,然後乘以結果。

>>> from functools import reduce 
>>> from itertools import product, starmap 
>>> from operator import mul 
>>> 
>>> def factors(prime_factors): 
...  primes, powers = zip(*prime_factors) 
...  power_combos = product(*(range(p + 1) for p in powers)) 
...  prime_combos = (zip(primes, c) for c in power_combos) 
...  return (reduce(mul, starmap(pow, c)) for c in prime_combos) 
... 
>>> sorted(factors([(2, 3), (3, 1)])) 
[1, 2, 3, 4, 6, 8, 12, 24] 

該代碼使用Python 3.0。除了致電sorted之外,它僅使用迭代器。

方備註:太糟糕了,這個問題似乎很不受歡迎。我想看看例如一些功能解決方案正在發佈(稍後我可能會試圖編寫一個Haskell解決方案。)

0

我先拍與problem #23無手頭的IDE所以有可能在有一些錯誤。

struct PrimePower 
{ 
    public PrimePower(Int32 prime, Int32 power) : this() 
    { 
     this.Prime = prime; 
     this.Power = power; 
    } 

    public Int32 Prime { get; private set; } 
    public Int32 Power { get; private set; } 
} 

然後就是這個遞歸函數。

public IEnumerable<Int32> GetFactors(IList<PrimePowers> primePowers, Int32 index) 
{ 
    if (index < primePowers.Length() - 1) 
    { 
     Int32 factor = 1; 
     for (Int32 p = 0; p <= primePowers[index].Power; p++) 
     { 
      yield return factor * GetFactors(primePowers, index + 1); 
      factor *= primePowers[index].Prime; 
     } 
    } 
    else if (index = primePowers.Length() - 1) 
    { 
     Int32 factor = 1; 
     for (Int32 p = 0; p <= primePowers[index].Power; p++) 
     { 
      yield return factor * GetFactors(primePowers, index + 1); 
      factor *= primePowers[index].Prime; 
     } 
    } 
    else 
    { 
     throw new ArgumentOutOfRangeException("index"); 
    } 
} 

它也可能是一個擴展方法和IList<PrimerPower>可能會削弱IEnumerable<PrimePower>與幾個Skip()Take()電話。我也不喜歡通過指數,但替代方案是複製每次通話的主要功率列表。因此,我認爲迭代解決方案會更好 - 如果我再次擁有IDE,就會添加一個解決方案。

6

Haskell

cartesianWith f xs = concatMap $ \y -> map (`f` y) xs 
factorsOfPrimeFactorization = 
    foldl (cartesianWith (*)) [1] . map (\(p, e) -> map (p^) [0..e]) 
 
> factorsOfPrimeFactorization [(2, 3), (3, 1)] 
[1,2,4,8,3,6,12,24] 

排序結果,

import Data.List 
cartesianWith f xs = concatMap $ \y -> map (`f` y) xs 
factorsOfPrimeFactorization = 
    sort . foldl (cartesianWith (*)) [1] . map (\(p, e) -> map (p^) [0..e]) 

Perl

sub factors { 
    my %factorization = @_; 
    my @results = (1); 
    while (my ($p, $e) = each %factorization) { 
     @results = map {my $i = $_; map $i*$_, @results} map $p**$_, 0..$e; 
    } 
    sort {$a <=> $b} @results; 
} 

print join($,, factors(2, 3, 3, 1)), $/; # => 1 2 3 4 6 8 12 24 

J

 
    /:~~.,*/"1/{:@({.^[email protected]{:@>:)"1 ] 2 3 ,: 3 1 
1 2 3 4 6 8 12 24 

這些都實現相同的算法,這是爲了生成列表pp ,&hellip;,pË每個對(p,e)進行因式分解,取其乘積每個列表都在笛卡爾積中設置。

3

如果你不關心單個除數,但對n個全部約數的總和,你可能想看看Divisor Function

因此除數的

n=p_1^{a_1}\cdot p_2^{a_2}\cdots p_k^{a_k}總和

\frac{p_1^{a_1+1}-1}{p_1-1}\cdot\cdot\cdot\frac{p_k^{a_k+1}-1}{p_k-1}

-1

很容易做到的。事實上,我在我的博客上寫了一篇關於這件事的文章。看看這個代碼。

#Application lists all factors/divisors for a number. 
targetNumber=input('What number do you want the factors for?\n> ') 
factors=[] 
for i in range(1,targetNumber): 
    if targetNumber%i==0: 
     factors.append(i) 
    elif targetNumber/i==1: 
     factors.append(targetNumber) 
     break 
print factors 

Read more

相關問題