Разность двух массивов java

Как вычесть массив из массива?

Необходимо найти разницу, те сравнить 2 массива и оставить только неповторяющиеся элементы. Порядок не важен. Дублирование значений в массивах исключено. Изначально известно что М1 содержит 50 элементов М2, их только нужно оттуда убрать. Долго не было ответа, решил вот так: Спасибо за помощь.

private int[] delArray(int[] a, int[] b) < Listlist_A = new ArrayList(); for (int index = 0; index < a.length; index++) < list_A.add(a[index]); >List list_B = new ArrayList(); for (int index = 0; index < b.length; index++) < list_B.add(b[index]); >list_A.removeAll(list_B); int[] ret = new int[list_A.size()]; for(int i = 0;i

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

2 ответа 2

final int[] a1 = ; final int[] a2 = ; List intList = new ArrayList() >; List intList_2 = new ArrayList() >; intList.removeAll(intList_2); for (int a : intList) System.out.println(a); 

В случае, если порядок элементов неважен и входные массивы не содержат дублирующихся эллементов, то самый простой путь — создать Set из массива и удалить из него все элементы, содержащиеся во втором массиве:

Проблема лишь в том, как нормально создать Set из массива. Стандартный конструктор HashSet принимает Collection , поэтому необходимо преобразовать int[] в список (к примеру). Если есть поддержка Google Guava, то можно воспользоваться стандартным методом Ints.asLists . Его сложность в документации не указана, но если заглянуть в реализацию, то можно увидеть, что это О(1):

int[] m1 = new int[]; int[] m2 = new int[]; Set s = new HashSet<>(Ints.asList(m1)); s.removeAll(Ints.asList(m2)); s.forEach(System.out::println); 

В противном случае можно создать свой метод для создания множества из целочисленного массива:

public static Set asSet(int[] arr) < Sets = new HashSet<>(); for (int x : arr) < s.add(x); >return s; > 

Ну а если есть поддержка Java 8 (полагаю, в рамках Android это пока неуместно, но все же), то можно воспользоваться Stream :

Set s = IntStream.of(m1).boxed().collect(toSet()); s.removeAll(IntStream.of(m1).boxed().collect(toList())); s.forEach(System.out::println); 

Если элементов немного, то можно обойтись без множеств а просто проверить все элементы (осторожно: квадратичная сложность):

IntStream.of(m1).filter(x -> IntStream.of(m2).noneMatch(y -> x == y)).forEach(System.out::println); 

Источник

Читайте также:  Make a Website Using HTML/CSS

Реализация вычитания массивов [закрыт]

Закрыт. Этот вопрос необходимо уточнить или дополнить подробностями. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение.

Помогите с реализацией метода minus() , который принимает параметры 2 массива arr1 и arr2. В результате должен возвращать разницу между двумя массивами. Пояснение что в моем понимание разница — вернуть массив, элементы которого содержаться в arr1, но не и в arr2.

Что в вашем понимании разница массивов? Операция, аналогичная разности множеств? В чем загвоздка в таком случае? Создаете третий массив, внешний цикл по одному массиву, внутренний по второму, проверяете если элемент первого массива равен второму, значит эти два элемента в разность не включать. Если за один проход по второму циклу не нашли равный элемент, то добавляете текущий элемент первого массива в массив-разность. Приведите пример входных и выходных данных.

Как мне показалось, речь идёт о простой операции вычитания из элементов одного массива значений элементов другого массива.

@АлександрДерменжи если у вас простенькая задача, то можно вместо массивов использовать Коллекции и в частности использовать метод removeAll . А вот если у вас действительно массивы и жестко на них завязаны и логика уже есть всего для них — будет совсем другое решение. но интересно было бы, что у вас есть и что вы пытались сделать

Источник

How can I return the difference between two lists?

If you want the disjunction between the two, CollectionUtil has a disjunction method that returns the difference.

This might be referring to CollectionUtils.subtract from Apache Commons Collections; see this answer for more details.

12 Answers 12

You can convert them to Set collections, and perform a set difference operation on them.

Set ad = new HashSet(a); Set bd = new HashSet(b); ad.removeAll(bd); 

That’s correct, but when you look at the documentation you will see that this boolean informs wether or not «this set changed as a result of the call». After this change you can adres the Set and you’ll notice it has the results you expected.

If you only want find missing values in b, you can do:

List toReturn = new ArrayList(a); toReturn.removeAll(b); return toReturn; 

If you want to find out values which are present in either list you can execute upper code twice. With changed lists.

I was looking similar but I wanted the difference in either list (uncommon elements between the 2 lists).

List oldKeys = Arrays.asList("key0","key1","key2","key5"); List newKeys = Arrays.asList("key0","key2","key5", "key6"); 

And I wanted to know which key has been added and which key is removed i.e I wanted to get (key1, key6)

List list = new ArrayList<>(CollectionUtils.disjunction(newKeys, oldKeys)); 

Could you point me to the maven repository for the same. I tried this https://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.4 But it does not seem to be the right one.

You can use filter in the Java 8 Stream library

List aList = List.of("l","e","t","'","s"); List bList = List.of("g","o","e","s","t"); List difference = aList.stream() .filter(aObject -> < return ! bList.contains(aObject); >) .collect(Collectors.toList()); //more reduced: no curly braces, no return List difference2 = aList.stream() .filter(aObject -> ! bList.contains(aObject)) .collect(Collectors.toList()); 

Result of System.out.println(difference); :

You can use CollectionUtils from Apache Commons Collections 4.0:

new ArrayList<>(CollectionUtils.subtract(a, b)) 

Note: this approach does not support generics in any way, so what you get is a raw, un-checked Collection instance.

The method signature is: public static Collection subtract(Iterable a, Iterable b) , and according to documentation: «O — the generic type that is able to represent the types contained in both input collections.»

You are indeed correct; mea culpa. I was looking at the 3.2 version of the class where the method has a simple public static Collection subtract(final Collection a, final Collection b) signature. Great to see that they have improved on this in the 4.0 iteration.

First convert list to sets.

// create an empty set Set set = new HashSet<>(); // Add each element of list into the set for (T t : list) set.add(t); 

You can use Sets.difference(Set1, Set2) , which returns extra items present in Set1.
You can use Sets.difference(Set2, Set1) , which returns extra items present in Set2.

With Stream API you can do something like this:

List aWithoutB = a.stream() .filter(element -> !b.contains(element)) .collect(Collectors.toList()); List bWithoutA = b.stream() .filter(element -> !a.contains(element)) .collect(Collectors.toList()); 

Here is a generic solution for this problem.

public List difference(List first, List second) < ListtoReturn = new ArrayList<>(first); toReturn.removeAll(second); return toReturn; > 
List l1 = new ArrayList(); l1.add("apple"); l1.add("orange"); l1.add("banana"); l1.add("strawberry"); List l2 = new ArrayList(); l2.add("apple"); l2.add("orange"); System.out.println(l1); System.out.println(l2); for (String A: l2) < if (l1.contains(A)) l1.remove(A); >System.out.println("output"); System.out.println(l1); 
[apple, orange, banana, strawberry] [apple, orange] output [banana, strawberry] 

You may call Underscore.difference(lists) method in underscore-java library. Live example

import com.github.underscore.Underscore; import java.util.Arrays; import java.util.List; public class Main < public static void main(String[] args) < Listlist1 = Arrays.asList(1, 2, 3); List list2 = Arrays.asList(1, 2); List list3 = Underscore.difference(list1, list2); System.out.println(list3); // [3] > > 

I was looking for a different problem and came across this, so I will add my solution to a related problem: comparing two Maps.

 // make a copy of the data Map a = new HashMap(actual); Map e = new HashMap(expected); // check *every* expected value for(Map.Entry val : e.entrySet()) < // check for presence if(!a.containsKey(val.getKey()))< System.out.println(String.format("Did not find expected value: %s", val.getKey())); >// check for equality else < if(0 != a.get(val.getKey()).compareTo(val.getValue()))< System.out.println(String.format("Value does not match expected: %s", val.getValue())); >// we have found the item, so remove it // from future consideration. While it // doesn't affect Java Maps, other types of sets // may contain duplicates, this will flag those // duplicates. a.remove(val.getKey()); > > // check to see that we did not receive extra values for(Map.Entry val : a.entrySet())

It works on the same principle as the other solutions but also compares not only that values are present, but that they contain the same value. Mostly I’ve used this in accounting software when comparing data from two sources (Employee and Manager entered values match; Customer and Corporate transactions match; . etc)

Источник

differences between two arrays [duplicate]

1. Does the order matter? 2. What about duplicate elements? 3. What about elements that are added in the second array? 4. What about the index of each difference. — Bottom line: could you please supply a few more less trivial examples so that we can understand what exactly you are asking?

@Oleg, sure, but in a suboptimal way. This question is getting answers, is not covered by the existing question, and shouldn’t be deleted.

2 Answers 2

new HashSet(Arrays.asList(array)); 
Set commonOnes = biggerSet.retainAll(smallerSet); biggerSet.removeAll(commonOnes).add(smallerSet.removeAll(commonOnes)) 

This only works if: 1. The order doesn’t matter, 2. The if an element shows up twice in one and once in the other still means equal. It might work for the asker but warning.

retainAll returns a boolean and modifies the Set . The Javadoc for the method says, «. removes from this set all of its elements that are not contained in the specified collection.» removeAll behaves similarly.

This runs in O(n log n + m log m) , where n is the size of first , and m is the size of second . Basically, it sorts the arrays, then pass through each one, adding ones that don’t match to the LinkedList at each opportunity, then makes an array at the end. The earlier revision of this code did not work correctly because the trailing elements in the longer list were not getting added at the end.

public class SetDifference < public static void main(String. args) < String[] arrA = ; String[] arrB = ; System.out.println(Arrays.toString(differences(arrA, arrB))); > public static String[] differences(String[] first, String[] second) < String[] sortedFirst = Arrays.copyOf(first, first.length); // O(n) String[] sortedSecond = Arrays.copyOf(second, second.length); // O(m) Arrays.sort(sortedFirst); // O(n log n) Arrays.sort(sortedSecond); // O(m log m) int firstIndex = 0; int secondIndex = 0; LinkedListdiffs = new LinkedList(); while (firstIndex < sortedFirst.length && secondIndex < sortedSecond.length) < // O(n + m) int compare = (int) Math.signum(sortedFirst[firstIndex].compareTo(sortedSecond[secondIndex])); switch(compare) < case -1: diffs.add(sortedFirst[firstIndex]); firstIndex++; break; case 1: diffs.add(sortedSecond[secondIndex]); secondIndex++; break; default: firstIndex++; secondIndex++; >> if(firstIndex < sortedFirst.length) < append(diffs, sortedFirst, firstIndex); >else if (secondIndex < sortedSecond.length) < append(diffs, sortedSecond, secondIndex); >String[] strDups = new String[diffs.size()]; return diffs.toArray(strDups); > private static void append(LinkedList diffs, String[] sortedArray, int index) < while(index < sortedArray.length) < diffs.add(sortedArray[index]); index++; >> > 

Источник

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