您将获得一个数字的所有主要因子及其多重性(最高权力) 要求是产生该数字的所有因素。
让我举个例子:
素数因素:
(意思是数字为2^3 * 3^1 = 24
)
预期结果是:
1,2,3,4,6,8,12,24
我正在考虑使用一些链式自定义迭代器(在C#中),每个素数因子一个,从0到该素数的幂。
你会如何实现这个?使用您的首选语言。
中的Project Euler有关答案 0 :(得分:6)
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])
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
/:~~.,*/"1/{:@({.^i.@{:@>:)"1 ] 2 3 ,: 3 1 1 2 3 4 6 8 12 24
这些都实现了相同的算法,即生成列表 p 0 , p 1 ,分解中的每一对( p , e )中的..., p e ,并将笛卡尔积中每一组的乘积放在所有这些列表中。
答案 1 :(得分: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解决方案。)
答案 2 :(得分:3)
答案 3 :(得分:0)
我首先在没有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,则添加一个。
答案 4 :(得分:-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