Сравнение двух списков для уникальных предметов в каждом
У меня есть две коллекции (они являются массивами, но я думаю, что это не имеет значения): L
а также R
, Они оба отсортированы, и теперь я хочу сравнить их. Я хочу получить две коллекции: по одной для каждого входного массива, содержащего элементы, которых не было в другой.
Я мог бы просто взять первый предмет из L
а затем искать R
и, если нет совпадения, добавьте его в мою "уникальную" коллекцию (Lu
). Но это крайне неэффективно, и я ожидаю, что в ближайшем будущем будет несколько очень больших коллекций для обработки.
Я думал о возможной игре в классики:
Шаг 1: возьмите два списка,
L
а такжеR
и сравните заголовок каждого списка (l :: L
а такжеr :: R
):Ветвь 1: если
l
<r
, затем добавьтеl
вLu
и рекурсировать, проходя вL
а такжеr :: R
Ветвь 2: если
l
>r
, затем добавьтеr
вRu
и рекурсировать, проходя вl :: L
а такжеR
Филиал 3: если
l
знак равноr
потом рекурсировать, проходя вL
а такжеR
Шаг 2: возврат
Lu
а такжеRu
Я могу написать эту функцию, но прежде чем приложить усилия, мне было интересно, существует ли функция, которая может сделать это для меня. Кажется, это не редкий сценарий, и я всегда предпочел бы использовать существующее решение для развертывания своего собственного.
(Также, если есть более узнаваемое имя для этого алгоритма, я хотел бы знать, как он называется.)
1 ответ
(Я написал вопрос выше около 2 часов назад. С тех пор я нашел ответ самостоятельно. Вот что я обнаружил.)
В теории множеств "список" элементов в L, но не в R известен как "относительное дополнение R в L", также известный как "теоретико-множественное различие L и R"
(См. Статью Википедии " Дополнение (теория множеств)")
F#, будучи математическим языком, внедрил эту концепцию прямо в свою библиотеку Core. Во-первых, вам нужно собрать свои коллекции в виде наборов:
// example arrays:
let arr1 = [| 1; 2; 3 |]
let arr2 = [| 2; 3; 4 |]
// build the L and R sets
let L = set arr1
let R = set arr2
Теперь вы можете вызвать функцию "разности" и быстро получить относительное дополнение для каждого массива:
let Lu = Set.difference L R |> Set.toArray
let Ru = Set.difference R L |> Set.toArray
> val Lu : int [] = [|1|]
> val Ru : int [] = [|4|]
Там также более короткий синтаксис. Тип Set перегружен оператором минус. Set.difference
просто вычитает второй параметр из первого, так что вы можете просто использовать следующее:
let Lu = L - R |> Set.toArray
let Ru = R - L |> Set.toArray
> val Lu : int [] = [|1|]
> val Ru : int [] = [|4|]