Найти пересечение массивов java

Пересечение между двумя целочисленными массивами

В этом кратком руководстве мы рассмотрим, как использоватьcompute the intersection between two Integer arrays ‘a’ и‘b’.

Мы также сосредоточимся на том, как обрабатывать повторяющиеся записи.

Для реализации мы будем использоватьStreams.

2. Предикат членства для массива

Пересечение двух наборов по определению является набором со всеми значениями из одного, которые также являются частью второго набора.

Поэтому нам нуженFunction или, скорее,Predicate, чтобы определить членство во втором массиве. ПосколькуList предоставляет такой метод из коробки, мы преобразуем его вList:

Predicate isContainedInB = Arrays.asList(b)::contains;

3. Строительство перекрестка

Чтобы создать результирующий массив, мы последовательно рассмотрим элементы первого набора и проверим, содержатся ли они также во втором массиве. Затем мы создадим новый массив на основе этого.

Stream API предоставляет нам необходимые методы. First, we’ll create a Stream, then filter with the membership-Predicate and finally we’ll create a new array:

public static Integer[] intersectionSimple(Integer[] a, Integer[] b)

4. Повторяющиеся записи

Поскольку массивы в Java не являются реализациейSet, мы сталкиваемся с проблемой дублирования записей во входных данных, а затем и в результате. Обратите внимание, что количество вхождений в результате зависит от вхождений в первом параметре.

Читайте также:  Встроенные функции python системы счисления

Но для наборов элементы не должны встречаться несколько раз. We can archive this by using the distinct() method:с

public static Integer[] intersectionSet(Integer[] a, Integer[] b)

Таким образом, длина пересечения больше не зависит от порядка параметров.

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

5. Multiset Intersection

Более общим понятием, которое допускает множественные равные записи, являются мультимножества. Для них пересечение определяется минимальным количеством входных вхождений. Таким образом, наше членство —Predicate должно отслеживать, как часто мы добавляем элемент к результату.

Для этого можно использовать методremove(), который возвращает членство и потребляет элементы. Таким образом, после того, как все равные элементы в‘b’ потреблены, к результату больше не добавляются равные элементы:

public static Integer[] intersectionSet(Integer[] a, Integer[] b)< return Stream.of(a) .filter(new LinkedList<>(Arrays.asList(b))::remove) .toArray(Integer[]::new); >

ПосколькуArrays API возвращает только неизменяемыйList,, мы должны создать специальный изменяемый.

6. Заключение

В этой статье мы увидели, как использовать методыcontains иremove для реализации пересечения двух массивов в Java.

Всю реализацию, фрагменты кода и тесты можно найти в нашемGithub repository — это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.

Источник

Пересечение между двумя целочисленными массивами

В этом кратком руководстве мы рассмотрим, как вычислить пересечение двух массивов целых чисел «a» и «b» .

Мы также сосредоточимся на том, как обрабатывать повторяющиеся записи.

Для реализации мы будем использовать Streams.

2. Предикат членства для массива

Пересечение двух множеств по определению представляет собой множество со всеми значениями из одного, которые также являются частью второго множества.

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

 Predicate isContainedInB = Arrays.asList(b)::contains; 

3. Строительство перекрестка

Чтобы построить результирующий массив, мы последовательно рассмотрим элементы первого набора и проверим, содержатся ли они также во втором массиве. « Затем мы создадим новый массив на основе этого.

Stream API предоставляет нам необходимые методы. Во- первых, мы создадим Stream , затем отфильтруем с помощью Member — Predicate и, наконец, создадим новый массив:

 public static Integer[] intersectionSimple(Integer[] a, Integer[] b)   return Stream.of(a)   .filter(Arrays.asList(b)::contains)   .toArray(Integer[]::new);   > 

4. Повторяющиеся записи

Поскольку массивы в Java не являются реализацией Set , мы сталкиваемся с проблемой дублирования записей во входных данных, а затем в результате. Обратите внимание, что количество вхождений в результате зависит от вхождений в первом параметре.

Но для наборов элементы не должны встречаться несколько раз. Мы можем заархивировать это, используя метод Different() :

 public static Integer[] intersectionSet(Integer[] a, Integer[] b)   return Stream.of(a)   .filter(Arrays.asList(b)::contain)   .distinct()   .toArray(Integer[]::new);   > 

Таким образом, длина пересечения больше не зависит от порядка параметров.

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

5. Мультимножественное пересечение

Более общее понятие, допускающее несколько одинаковых записей, — это мультимножества. Для них пересечение затем определяется минимальным количеством входных вхождений. Таким образом, наш предикат членства должен вести учет того, как часто мы добавляем элемент к результату.

Для этого можно использовать метод remove() , который возвращает членство и использует элементы. Таким образом, после того, как все равные элементы в «b» использованы, к результату больше не добавляются равные элементы:

 public static Integer[] intersectionSet(Integer[] a, Integer[] b)   return Stream.of(a)   .filter(new LinkedList>(Arrays.asList(b))::remove)   .toArray(Integer[]::new);   > 

Поскольку Arrays API возвращает только неизменяемый список, мы должны создать специальный изменяемый список.

6. Заключение​

В этой статье мы увидели, как использовать методы contains и remove для реализации пересечения двух массивов в Java.

Всю реализацию, фрагменты кода и тесты можно найти в нашем репозитории GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.

Источник

Java, найти пересечение двух массивов

Я пытаюсь изучить два массива, а также их количество элементов (numElementsInX и numElementsInY) и вернуть новый массив, который содержит общие значения массива x и y. Их пересечение.

Example,if x isand y is then intersection(x, 5, y, 4> should return or

Я прочитал, мне нужно использовать алгоритм LCS. Может ли кто-нибудь дать мне пример, как это сделать? И массив, и значения в массиве инициализируются и генерируются другим методом, а затем передаются в пересечение. Любая помощь/разъяснение оценены. EDIT CODE

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

6 ответов

Простейшим решением было бы использование наборов, если вам не все равно, что элементы в результате будут иметь другой порядок и дубликаты будут удалены. Входные массивы array1 и array2 являются подмассивами Integer[] данных массивов int[] , соответствующих количеству элементов, которые вы собираетесь обрабатывать:

Set s1 = new HashSet(Arrays.asList(array1)); Set s2 = new HashSet(Arrays.asList(array2)); s1.retainAll(s2); Integer[] result = s1.toArray(new Integer[s1.size()]); 

Вышеуказанное вернет Integer[] , если необходимо, просто скопировать и преобразовать его содержимое в int[] .

Кроме того, это не сохранит дубликаты — даже если и array1 и array2 имеют множественные вхождения x , эти дубликаты не сохранятся.

s2 не должен быть набором, поэтому вы можете удалить new HashSet вызов конструктора new HashSet и оставить его Collection — это может немного повысить производительность.

Если вы в порядке с java-8, то самым простым решением, которое я могу думать, является использование потоков и фильтра. Реализация следующая:

public static int[] intersection(int[] a, int[] b) < return Arrays.stream(a) .distinct() .filter(x ->Arrays.stream(b).anyMatch(y -> y == x)) .toArray(); > 

Это неверно Рассмотрим этот случай: a = [1,2,2,1] b = [2] Ответ должен быть [2], но это дает ответ как [2,2]

это все еще не работает. Возьмем a = [1,2,2,1] и b = [2,2]. Ответ должен быть [2,2], но это дает ответ как [2]

@UjjwalGulecha Насколько я знаю, вы либо заботитесь о дубликатах, либо нет. Вы можете остановиться на этом? Не уверен, что я что-то упустил.

NVM. ОП спросил, каков твой ответ. Я искал пересечение с дубликатами, разрешенными в основном, то есть, если A имеет n x и B имеет n-1 x, их пересечение должно иметь n-1 x.

Если вы не хотите использовать другие структуры данных, такие как набор, то основная идея заключается в том, что вы хотите итерации по элементам одного из массивов, и для каждого значения посмотрите, появляется ли оно в другом. Как вы видите, появляется ли он в другом массиве? Пройдите через элементы в другом массиве и для каждого из них, посмотрите, совпадает ли его значение со значением, которое вы ищете. Я подозреваю, что вам будет лучше всего работать, пытаясь справиться с этой проблемой самостоятельно, если ваша цель в классе — научиться хорошо писать Java, но вы застряли, можете подумать о том, чтобы обновить свой вопрос с помощью кода которые вы написали, чтобы вы могли получить более подробную обратную связь и указатели в правильном направлении.

Источник

Пересечение двух списков в Java

В этом уроке мы узнаем, как получить пересечение двух List s .

Как и многое другое, это стало намного проще благодаря внедрению потоков в Java 8 .

2. Пересечение двух списков строк

Давайте создадим два List s из String с некоторым пересечением — оба содержат дублирующиеся элементы:

 ListString> list = Arrays.asList("red", "blue", "blue", "green", "red");   ListString> otherList = Arrays.asList("red", "green", "green", "yellow"); 

А теперь определим пересечение списков с помощью потоковых методов :

 SetString> result = list.stream()   .distinct()   .filter(otherList::contains)   .collect(Collectors.toSet());    SetString> commonElements = new HashSet(Arrays.asList("red", "green"));    Assert.assertEquals(commonElements, result); 

Во-первых, мы удаляем повторяющиеся элементы с разными . Затем мы используем фильтр для выбора элементов, которые также содержатся в otherList .

Наконец, мы преобразуем наш вывод с помощью Collector . Пересечение должно содержать каждый общий элемент только один раз. Порядок не должен иметь значения, поэтому toSet — самый простой выбор, но мы также можем использовать toList или другой метод сбора.

Дополнительные сведения см. в нашем руководстве по коллекторам Java 8 .

3. Пересечение списков пользовательских классов

Что, если наши List содержат не String , а экземпляры пользовательского класса, который мы создали? Ну, пока мы следуем соглашениям Java, решение с потоковыми методами будет прекрасно работать для нашего пользовательского класса.

Как метод contains решает, появляется ли конкретный объект в списке? На основе метода равных . Таким образом, мы должны переопределить метод equals и убедиться, что он сравнивает два объекта на основе значений соответствующих свойств.

Например, два прямоугольника равны, если их ширина и высота равны.

Если мы не переопределяем метод equals , наш класс использует реализацию equals родительского класса. В конце дня, вернее, в цепочке наследования выполняется метод equals класса Object . Тогда два экземпляра равны, только если они ссылаются на один и тот же объект в куче. «

Для получения дополнительной информации о методе equals см. нашу статью о контрактах Java equals() и hashCode() .

4. Вывод

В этой быстрой статье мы увидели, как использовать потоки для вычисления пересечения двух списков. Есть много других операций, которые раньше были довольно утомительными, но довольно простыми, если мы знаем, как работать с Java Stream API. Взгляните на наши дальнейшие руководства с потоками Java здесь .

Источник

Оцените статью