Поскольку у вас уже есть список основных факторов, вы хотите вычислить набор параметров этого списка.
Теперь одна проблема состоит в том, что в списке могут быть дубликаты (например, простые множители 20 = 2 * 2 * 5), но наборы не допускают дубликатов.Таким образом, мы можем сделать каждый элемент списка уникальным, проецируя его на структуру вида {x, y}, где x - простое число, а y - индекс простого числа в списке.
var all_primes = primes.Select((x, y) => new { x, y }).ToList();
Теперь all_primes
- это список вида {x, y}, где x - это простое число, а y - индекс в списке.
Затем мы вычисляем набор мощности (определение GetPowerSet
ниже):
var power_set_primes = GetPowerSet(all_primes);
Следовательно, 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);
}
Собираем все вместе:
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);
}
От 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];
}