2013-06-25 7 views
15

Предположим, у меня есть массив, arrayA = ["a", "b", "c", "d", "e", "f"], и еще один массив arrayB = ["a", " d "," e "].Как вычесть один массив символов из другого в Java?

Я хочу, чтобы вычесть arrayB из Arraya с получением результата = [ "B", "C", "п"]

Это моя установка для каждого массива:

char[] arrayA = new char[7]; 
for(char c = 'a'; c <= 'f'; ++c) { 
    arrayA[c - 'a'] = c; 
} 
char[] arrayB = new char[]{'a','d','e'}; 

(Пожалуйста, извините за любое неправильное использование символов и синтаксиса, я Ruby noob, пытающийся изучить Java просто из учебников Oracle. Спасибо!) edit: слово и цитаты

+6

Подсказка: пропустите массивы и перейдите непосредственно к коллекциям (в частности, 'List' /' ArrayList'). Массивы - это довольно низкоуровневые инструменты, которые вы редко должны использовать непосредственно в Java (кроме, возможно, для 'byte []'). –

+1

LOL этот пост upvote небеса! –

+1

Что вы хотите, если у вас есть несколько одинаковых элементов в 'arrayA'? Что вы хотите, если в 'arrayB' есть элементы, которые не отображаются в' arrayA'? Сохраняет ли порядок элементов, которые вы сохраняете? –

ответ

24

Короткий ответ - преобразовать ваши массивы в «наборы ", а затем использовать для них заданные операции. Я ищу правильный код для этого прямо сейчас, но вы можете начать с проверки этого сообщения: Classical set operations for java.util.Collection

Редактировать: Luke657 поднимает хороший момент. примитивные массивы являются странными. Так ниже обновленный код:

Предполагая, что вы начинаете с массив символов (это, конечно, будет лучше начать с набора, ну да ладно):

char[] arrayA = new char[] {'a', 'b', 'c', 'd', 'e', 'f'}; 
char[] arrayB = new char[] {'a', 'd', 'e'}; 
Character[] objarrayA = ArrayUtils.toObject(arrayA); 
Character[] objarrayB = ArrayUtils.toObject(arrayB); 
Set<T> setA = new HashSet(Arrays.asList(objarrayA)); 
Set<T> setB = new HashSet(Arrays.asList(objarrayB)); 

setA.removeAll(setB); 

Затем, чтобы получить его обратно a char array:

Character[] result; 
result = setA.toArray(result); 
char[] cresult = ArrayUtils.toPrimitive(result); 

Я считаю, что это сделает то, что вам нужно. Операцией Arrays.asList() является O (1), поэтому она эффективна и не является дорогостоящей, поэтому не беспокойтесь об этом дополнительном преобразовании.

+1

не знаю. вероятно, потому, что я сказал, что не буду беспокоиться о публикации кода, поскольку user2503916 имеет его ниже. Хм, хорошо, возможно, у меня есть идея. –

+0

lol, я думаю, что это была ошибка. :) – PermGenError

+6

Если ваш ответ будет отменен, я думаю, вы должны включить код. Будущим пользователям будет только читать ваш ответ вместо прокрутки, чтобы найти код. =) – Goatcat

7

Я предлагаю вам построить Set от arrayA, а затем вызвать removeAll на нем, используя второй массив.

Если два массива отсортированы, как показано в вашем вопросе, вы можете решить проблему с помощью одной итерации по массивам.

12

конвертировать их в список и вызвать removeAll метод:

Character[] array1 = ArrayUtils.toObject(arrayA); 
    Character[] array2 = ArrayUtils.toObject(arrayB);  
    List<Character> list1 = new ArrayList(Arrays.asList(array1)); 
    List<Character> list2 = new ArrayList(Arrays.asList(array2)); 
    list1.removeAll(list2);` 
+0

Это отлично! Я не знал о '.asList()'. Спасибо, что поделился! – Goatcat

+8

Это приведет к исключению среды выполнения. 'Arrays.asList' возвращает un-modifiable список. Вам нужно создать новый список. –

+1

Throws 'java.lang.UnsupportedOperationException' будет более конкретным. – m0skit0

2
import java.util.Collection; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class Repeated { 

public static void main(String[] args) { 
//  Collection listOne = new ArrayList(Arrays.asList("a", "b", "c", "d", "e", "f")); 
//  Collection listTwo = new ArrayList(Arrays.asList("a", "d", "e")); 
// 
//  listOne.retainAll(listTwo); 
//  System.out.println(listOne); 

    String[] s1 = {"a", "b", "c", "d", "e", "f"}; 
    String[] s2 = {"a", "d", "e"}; 
    List<String> s1List = new ArrayList(Arrays.asList(s1)); 
    for (String s : s2) { 
     if (s1List.contains(s)) { 
      s1List.remove(s); 
     } else { 
      s1List.add(s); 
     } 
     System.out.println("intersect on " + s1List); 
    } 
} 
} 
+0

Не изобретайте велосипед. – m0skit0

+1

Существует ['Collection.removeAll()'] (http://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#removeAll (java.util.Collection)). –

+0

Это, вероятно, будет медленнее, чем предлагаемые методы removeAll() –

2

Arrays.asList не работает с примитивными типами, как полукокса, так что вы должны перебирать обоих массивов, изменять их в обертке class Character и добавьте их к наборам. Затем вы можете использовать метод removeAll.

Set<Character> setA = new HashSet<>(); 
Set<Character> setB = new HashSet<>(); 
for(int i = 0; i < arrayA.length; i++){ 
    setA.add(new Character(arrayA[i])); 
} 
for(int i = 0; i < arrayB.length; i++){ 
    setA.add(new Character(arrayB[i])); 
} 
setA.removeAll(setB); 
arrayA = new char[setA.size()]; 
int i = 0; 
for(Character c : setA){ 
    arrayA[i++] = c.charValue(); 
} 
2

Преобразование массивов в списки (например, ArrayList) с помощью Arrays.asList(). Общие наборы не принимают примитивных типов (так asList не будет работать на массивах, как сейчас), так что вы можете использовать объект набора символов вместо так:

Character a[] = {'f', 'x', 'l', 'b', 'y'}; 
Character b[] = {'x', 'b'}; 
ArrayList<Character> list1 = new ArrayList<Character>(Arrays.asList(a)); 
ArrayList<Character> list2 = new ArrayList<Character>(Arrays.asList(b)); 
list1.removeAll(list2); 

Читайте о родовых типах здесь, в случае, если вы незначителен: http://docs.oracle.com/javase/tutorial/java/generics/types.html

Если вам нужны массивы, вы можете использовать функцию arArray() ArrayList для воссоздания массива.