Порядок листов учета пересечения элементов


Я мог бы использовать функцию пересечения, но она возвращает отсортированный список. Вот почему я должен сделать мои собственные, но это выглядит слишком большой. Я надеюсь, что это может быть сделано короче.

lists = {{1, 2, 3, 4, 5}, {1, 2, 3, 4}, {2, 3, 4, 5}};
Fold[ Function[ {a, b},
  Select[b, MemberQ[a, #] &]
  ], lists // First, lists // Rest]


481
5
задан 13 апреля 2011 в 10:04 Источник Поделиться
Комментарии
3 ответа

Эта функция удаляет из первого списка все элементы, не содержащиеся на перекрестке, тем самым возвращая то, что вы хотите:

f[l_List]:= DeleteCases[First@l, Except[Alternatives @@ (Intersection @@ l)]]  

f[{{1, 2, 3, 4, 5}, {1, 2, 3, 4}, {2, 3, 4, 5}}]
->{2,3,4}

f[{{5, 7, 6, 3}, {5, 6, 1, 3}}]
->{5,6,3}

3
ответ дан 28 апреля 2011 в 06:04 Источник Поделиться

Зачем использовать обратный подход? Просто сделать это непосредственно!

Cases[First[list], Alternatives @@ Intersection @@ list]

Если скорость имеет значение, можно определить временные "тестер" функции внутри модуля , чтобы использовать в место MemberQ

Module[ {f},
(f[#] = True)& /@ (Intersection @@ list);
Select[First[list], f]
]

Это еще довольно короткий.

2
ответ дан 11 мая 2011 в 11:05 Источник Поделиться

Наиболее эффективным и простым способом для этого является сортировка каждого списка, прежде чем применять такой алгоритм.
В этом случае вы не должны проверить, если каждый число над другом списке, но вы просто выбрать первый ряд и сравнить с другими элементами из начала.

Это причина того, что система Mathematica возвращает отсортированный список. В случае, если каждый список отсортированный сложность o(n), где N-это общее количество всех элементов.

0
ответ дан 14 апреля 2011 в 06:04 Источник Поделиться