soa*_*dos 11 c# prime-factoring factorization
所以我只想找到给定数字的所有除数(除了数字本身).目前,我有这个:
public static List<int> proper_divisors(int x)
{
List<int> toreturn = new List<int>();
toreturn.Add(1);
int i = 0;
int j=1;
int z = 0;
while (primes.ElementAt(i) < Math.Sqrt(x))
{
if (x % primes.ElementAt(i) == 0)
{
toreturn.Add(primes.ElementAt(i));
toreturn.Add(x / primes.ElementAt(i));
j = 2;
z = (int)Math.Pow(primes.ElementAt(i), 2);
while (z < x)
{
if (x % z == 0)
{
toreturn.Add(z);
toreturn.Add(x / z);
j++;
z = (int)Math.Pow(primes.ElementAt(i), j);
}
else
{
z = x;
}
}
}
i++;
}
toreturn = toreturn.Distinct().ToList<int>();
return toreturn;
}
Run Code Online (Sandbox Code Playgroud)
其中primes是素数列表(假设它是正确的,并且足够大).该算法的工作原理在于它找到所有素因子,但不是所有因子(即给定34534,它返回{1,2,17267,31,1114}但是错过{62,557},因为62是一个组合,因此也错过了557.
我也尝试过获取数字的素数因子,但我不知道如何将其转换为所有正确组合的列表.
该算法的代码如下:
public static List<int> prime_factors(int x)
{
List<int> toreturn = new List<int>();
int i = 0;
while (primes.ElementAt(i) <= x)
{
if (x % primes.ElementAt(i) == 0)
{
toreturn.Add(primes.ElementAt(i));
x = x / primes.ElementAt(i);
}
else
{
i++;
}
}
return toreturn;
}
Run Code Online (Sandbox Code Playgroud)
关于如何修复第一个的任何想法,或者如何从第二个创建组合列表(我希望它会更快)?
由于您已经有一个素数因子列表,您要做的是计算该列表的powerset.
现在,一个问题是你可能在列表中有重复项(例如20 = 2*2*5的素数因子),但是集合不允许重复.因此,我们可以通过将列表的每个元素投影到{x,y}形式的结构来使列表中的每个元素唯一,其中x是素数,y是列表中素数的索引.
var all_primes = primes.Select((x, y) => new { x, y }).ToList();
Run Code Online (Sandbox Code Playgroud)
现在,all_primes是一个{x,y}形式的列表,其中x是素数,y是列表中的索引.
然后我们计算功率集(GetPowerSet下面的定义):
var power_set_primes = GetPowerSet(all_primes);
Run Code Online (Sandbox Code Playgroud)
因此,power_set_primes在IEnumerable<IEnumerable<T>>哪里T是匿名类型{x, y},其中x和y是类型int.
接下来,我们计算功率集中每个元素的乘积
foreach (var p in power_set_primes)
{
var factor = p.Select(x => x.x).Aggregate(1, (x, y) => x * y);
factors.Add(factor);
}
Run Code Online (Sandbox Code Playgroud)
把它们放在一起:
var all_primes = primes.Select((x, y) => new { x, y }).ToList(); //assuming that primes contains duplicates.
var power_set_primes = GetPowerSet(all_primes);
var factors = new HashSet<int>();
foreach (var p in power_set_primes)
{
var factor = p.Select(x => x.x).Aggregate(1, (x, y) => x * y);
factors.Add(factor);
}
Run Code Online (Sandbox Code Playgroud)
来自http://rosettacode.org/wiki/Power_Set,用于实现powerset.
public IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list)
{
return from m in Enumerable.Range(0, 1 << list.Count)
select
from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i];
}
Run Code Online (Sandbox Code Playgroud)
已经有过类似的问题之前,它有使用IEnumerable的一个有趣的解决方案.如果你想要所有的除数而不是因子,假设你至少使用C#3.0,你可以使用这样的东西:
static IEnumerable<int> GetDivisors(int n)
{
return from a in Enumerable.Range(2, n / 2)
where n % a == 0
select a;
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
foreach(var divisor in GetDivisors(10))
Console.WriteLine(divisor);
Run Code Online (Sandbox Code Playgroud)
或者,如果你想要一个List,只需:
List<int> divisors = GetDivisors(10).ToList();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13548 次 |
| 最近记录: |