Создание списка всех возможных комбинаций - PullRequest
2 голосов
/ 03 февраля 2012

Я пытаюсь сделать следующее.

Я хочу создать список всех возможных отношений между определенными вещами.

Например.Есть Мэри, Алиса, Джун, Синди, Элизабет, Бетти, Джекс

Я хотел бы создать все возможные комбинации для такого списка:

  • Мэри, Алиса
  • Мэри, июнь
  • Мэри Синди
  • Мэри, Джекс
  • Мэри, Алиса, июнь
  • Мэри, Алиса, Синди
  • Мэри, Алиса, Элизабет ...
  • Мэри, Алиса, Джекс
  • Мэри, Джун, Синди
  • Мэри, Джун, Элизабет ...
  • Мэри, Джун, Джекс
  • Мэри, Синди, Элизабет
  • Мэри, Синди, Бетти
  • Мэри, Синди, Джекс ...
  • Мэри, АлисаИюнь, Синди
  • Мэри, Алиса, Джун, Элизабет
  • Мэри, Алиса, Джун, Бетти ...
  • Мэри, Алиса, Джун, Синди, Элизабет
  • Мэри, Алиса, Джун, Синди, Бетти

Кто-нибудь знает способ сделать это в SQL, Access или C #?Если есть другой язык, который я могу использовать в БД, я буду очень признателен!

Спасибо, Мария

Ответы [ 5 ]

3 голосов
/ 04 февраля 2012

Вам могут понравиться рекурсивные запросы, используемые для этого многими современными серверами БД.

ACCESS не является одним из них: (

ниже приведен пример с postres

postgres=# with RECURSIVE y1(b,c,d) as (
postgres(#      with x1(a) as (
postgres(#              values('a')
postgres(#              union all
postgres(#              values ('b')
postgres(#              union all
postgres(#              values ('c')
postgres(#              union all
postgres(#              values ('d')
postgres(#      )
postgres(#      select a,a,1
postgres(#      from x1
postgres(#      union all
postgres(#      select a||b,a,d+1
postgres(#      from x1
postgres(#              join y1 on (a < c)
postgres(# )
postgres-# select *
postgres-# from y1;
  b   | c | d
------+---+---
 a    | a | 1
 b    | b | 1
 c    | c | 1
 d    | d | 1
 ab   | a | 2
 ac   | a | 2
 ad   | a | 2
 bc   | b | 2
 bd   | b | 2
 cd   | c | 2
 abc  | a | 3
 abd  | a | 3
 acd  | a | 3
 bcd  | b | 3
 abcd | a | 4
(15 rows)


postgres=#
2 голосов
/ 04 февраля 2012

SQL может быть очень хорош для такого рода вещей. Это становится липким, если вы хотите пойти очень широко, но если бы вы знали, что вы хотите все комбинации, скажем, до пяти пунктов:

DECLARE @things TABLE (n nvarchar(50));

INSERT INTO @things (n) VALUES ('Mary'),('Alice'),('June'),('Cindy'),('Elizabeth'),('Betty'),('Jax'), (null);

SELECT 
  ISNULL(t1.n + ',', '') 
  + ISNULL(t2.n + ',', '') 
  + ISNULL(t3.n+ ',', '') 
  + ISNULL(t4.n+ ',', '') 
  + ISNULL(t5.n, '') 
FROM @things AS t1
JOIN @things AS t2 ON 1=1
JOIN @things AS t3 ON 1=1
JOIN @things AS t4 ON 1=1
JOIN @things AS t5 ON 1=1
1 голос
/ 04 февраля 2012

Если вы имеете в виду блок питания , то вы можете использовать следующее в C #

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];
}

Использование:

var names = new List<string> { "Mary", "Alice", "June", "Cindy", "Elizabeth", "Betty", "Jax" };
var powerSet = GetPowerSet(names);
foreach (var nameCollection in powerSet)
{
  foreach (var name in nameCollection)
  {
    Console.Write(name);
  }
  Console.WriteLine();
}

Вы можете удалить любойколлекции с менее чем 2 именами, а также полный набор имен:

var cleaned = powerSet.Where(nc => nc.Count() > 1 && nc.Count() < names.Count());
0 голосов
/ 05 февраля 2012

Довольно неловко, но сработает или напишет SQL-процесс с вложенными циклами для каждого имени.

создать отдельную таблицу для каждого имени, например:

CREATE TABLE MARY(name VARCHAR(30));
INSERT INTO  MARY VALUES ("Mary");

{do the same for each different name and then}

SELECT * 
  FROM mary, 
       alice,
       june,
       cindy,
       elizabeth,
       betty,
       jax;

Это создаст декартово произведение без дублирования каких-либо имен!

0 голосов
/ 04 февраля 2012

Если у вас есть определенное количество элементов, например, Мэри, Алиса, Джун, Синди, Элизабет, Бетти, Джакс, 8 элементов в этом случае, вы можете вложить 8 циклов, чтобы отобразить каждую возможную перестановку элементов.Если число неизвестно, вам понадобится рекурсивная функция.

...