2010-08-28 10 views
31

Chcę mieć operacje łączenia, przecinania, różnicowania i odwracania w Javie.Jak wykonać dane sumaryczne, krzyżowe, różnicowe i odwrotne w java

Najpierw mają 2 przypadki ArrayList<Integer>

a = [0,2,4,5,6,8,10] 
b = [5,6,7,8,9,10] 

związek B powinna powrócić c = [0,2,3,4,5,6,7,8,9,10]

przecinają B powinna powrócić c = [5,8,10]

defference B powinna powrócić c = [0,2,3,4]

odwrotnej a = [10,8,6,5,4,2,0]

Coś takiego.

Jak zaimplementować tę metodę w Javie?


Aktualizacja: Muszę zacząć od tego szablonu:

package IntSet; 
import java.util.ArrayList; 
import java.util.Collection; 


public class IntSet { 

private ArrayList<Integer> intset; 

public IntSet(){ 
    intset = new ArrayList<Integer>(); 
} 

public void insert(int x){ 
    intset.add(x); 
} 

public void remove(int x){ 
    //implement here 
    intset.indexOf(x); 
} 

public boolean member(int x){ 
    //implement here 
    return true; 
} 

public IntSet intersect(IntSet a){ 
    //implement here 
    return a; 
} 

public IntSet union(IntSet a){ 
    //implement here 
    return a; 
} 

public IntSet difference(IntSet a){ 
    //implement here 
    IntSet b = new IntSet(); 
    return b; 
} 
+1

Znowu mówisz zestaw funkcji, ale trzeba korzystać z list. Tak więc funkcja wstawiania jest już błędna: nie testujesz duplikatów. – Landei

Odpowiedz

30
//Union 
List<Integer> c = new ArrayList<Integer>(a.size() + b.size()); 
addNoDups(c,a); 
addNoDups(c,b); 

private void addNoDups(List<Integer> toAddTo,List<Integer> iterateOver) { 
    for(Integer num:iterateOver){ 
     if(toAddTo.indexOf(num) == -1) { 
      toAddTo.add(num); 
     } 
    } 
} 

//intersection 
List<Integer> c = new ArrayList<Integer> (a.size() > b.size() ?a.size():b.size()); 
c.addAll(a); 
c.retainAll(b); 

//difference a-b 
List<Integer> c = new ArrayList<Integer> (a.size()); 
c.addAll(a); 
c.removeAll(b); 
+2

+1 za zwięzłą odpowiedź. Chociaż myślę, że mógłbyś użyć Hashset zamiast ArrayList, by odmienić punkt. – Hari

+0

+1 Ale ... To podejście może zarezerwować więcej miejsca, a następnie jest wymagane dla wynikowej listy "C". Może lepiej byłoby nie rezerwować tej przestrzeni w czasie tworzenia nowej tablicy ArrayList? –

+0

@DmytroDzyubak Złożoność wszystkich metod jest kwadratowa, co zwykle jest dużo gorsze niż użycie jakiejś zewnętrznej przestrzeni. Czasami może to być do przyjęcia, ale rozwiązanie przynajmniej wyraźnie to wymienia. – maaartinus

59

pierwszy, operacje można opisać (oprócz wstecznego) są określone operacje, nie wymienia czynności, więc używać HashSet lub (jeśli potrzebujesz zamówienia) TreeSet.

Set<Integer> a = new TreeSet<Integer>(Arrays.asList(new Integer[]{0,2,4,5,6,8,10})); 
    Set<Integer> b = new TreeSet<Integer>(Arrays.asList(new Integer[]{5,6,7,8,9,10})); 

    //union 
    Set<Integer> c = new TreeSet<Integer>(a); 
    c.addAll(b); 
    System.out.println(c); 

    //intersection 
    Set<Integer> d = new TreeSet<Integer>(a); 
    d.retainAll(b); 
    System.out.println(d); 

    //difference 
    Set<Integer> e = new TreeSet<Integer>(a); 
    e.removeAll(b); 
    System.out.println(e); 

    //reverse 
    List<Integer> list = new ArrayList<Integer>(a); 
    java.util.Collections.reverse(list); 
    System.out.println(list); 
+5

Jeśli zadeklarowałeś 'a' i' b' jako 'NavigableSet', możesz odwrócić ich kolejność za pomocą metody' descendingSet() '. Dla ogólnego "Setu" nie ma pojęcia porządku. – Natix

+0

Dobra odpowiedź, choć część odwrotna to nonsens. Powstał w kierownictwie PO, ale nie musieliście tego robić. Lub możesz dostarczyć zestaw z przeciwnym komparatorem. – Vlasec

8

Wiele odpowiedzi trzeba by korzystać z bibliotek, które będą pracować dla Ciebie. Chociaż jest to właściwe rozwiązanie dla prawdziwego świata, pamiętaj, że odrabiasz pracę domową, a Twój nauczyciel prawdopodobnie chce, abyś zrozumiał, jak są napisane funkcje, a nie tylko jak znaleźć biblioteki, które wykonają pracę za ciebie.

To powiedziawszy, masz dobry start z kodem, który pokazałeś. Weźmy problem krok po kroku.

Po pierwsze, czy wiesz, gdzie znajduje się dokumentacja Java? http://download.oracle.com/javase/1.4.2/docs/api/ ma to kluczowe znaczenie, ponieważ w ten sposób można dowiedzieć się, jakie funkcje są w stanie wykonać. Oto link do Java 1.4. Nie zauważyłem, jakiej wersji używasz, ale Java jest wstecznie kompatybilna, więc to powinno wystarczyć.

W dokumentach znajdź wpis ArrayList.

Teraz, gdy mamy dokumenty API, musimy podzielić twoje pytanie. publikujesz kod, więc adresuję go funkcją według funkcji.

wkładka(): czy musisz mieć uporządkowaną listę, czy zamówienie nie ma znaczenia? Czy masz gwarancję, że wartości zostaną dostarczone w porządku? Czy znasz już algorytmy sortowania?

remove(): ta funkcja nie działa. spójrz na interfejs API ArrayList i zobacz, jak usunąć element z listy. Użyj tej metody.

członek(): metoda członka nie działa. Musisz sprawdzić każdy wpis na liście i określić, czy bieżący członek pasuje do argumentu funkcji. Czy znasz już pętle?

przecięcie(): ok, powiedz mi po angielsku, co ma przecinać.Nie używaj opisu nauczyciela, jeśli możesz pomóc - użyj własnych słów (uwaga dla innych, jest to ćwiczenie dla OP, aby nauczyć się programować, więc proszę, nie odpowiadaj za niego)

różnica(): jeszcze raz powiedz mi po angielsku, co ma robić.

reverse(): jeszcze raz, daj mi angielski opis tego, co ma robić.

Po opisach w języku angielskim opisz algorytm, który może wykonać pracę. nie pisz jeszcze w Javie. po prostu napisz algorytm, w języku angielskim, opisujący sposób, w jaki wykonujesz pracę ręcznie, za pomocą pióra i papieru.

w tym miejscu spróbuj przekonwertować algorytm na kod Java.

18

Jeśli używasz zestawów (tak jak powinieneś, dla wszystkich z wyjątkiem odwrotnych to operacje Set), Guava udostępnia te operacje w swojej klasie Sets.

Set<Integer> union = Sets.union(set1, set2); 
Set<Integer> intersection = Sets.intersection(set1, set2); 
Set<Integer> difference = Sets.difference(set1, set2); 

Wszystkie z nich zwracają niemodyfikowalne widoki, poparte oryginalnymi Zestawami.

Zobacz Guava Explained ->Collection Utilities ->Sets

Jeśli Listy są co masz, można przekonwertować je do odbiornika za pomocą prezent konstruktora kopia we wszystkich standardowych kolekcji:

List<X> list = new ArrayList<>(); 
// fill up list here 
Set<X> set = new HashSet<>(list); 
0

Ten fragment znajdzie związek dwóch kolekcje używające Apache commons Metoda CollectionUtils.union

Collection<String> totalFriends = CollectionUtils.union(yourFriends, myFriends); 
+0

to było pytane sześć lat temu – sbowde4

1

Po prostu zostawię to tutaj. Jest nowy sposób z java-8 i streams

List<Integer> listA = Arrays.asList(0, 2, 4, 5, 6, 8, 10); 
List<Integer> listB = Arrays.asList(5, 6, 7, 8, 9, 10); 

List<Integer> intersection = listA.stream() 
     .filter(listB::contains) 
     .collect(Collectors.toList()); 

List<Integer> union = Stream.concat(listA.stream(), listB.stream()) 
     .distinct().sorted() 
     .collect(Collectors.toList()); 

List<Integer> aDiffB = listA.stream() 
     .filter(i -> !listB.contains(i)) 
     .collect(Collectors.toList()); 

System.out.println(intersection); // [5, 6, 8, 10] 
System.out.println(union); // [0, 2, 4, 5, 6, 7, 8, 9, 10] 
System.out.println(aDiffB); // [0, 2, 4] 
Powiązane problemy