2010-08-28 19 views
31

Tôi muốn có các hoạt động công đoàn, giao nhau, khác biệt và đảo ngược trong Java.Làm cách nào để thực hiện công đoàn, giao cắt, sự khác biệt và dữ liệu ngược trong java

Trước tiên tôi có 2 trường hợp của ArrayList<Integer>

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

một liên minh b nên trở c = [0,2,3,4,5,6,7,8,9,10]

một giao nhau b nên trở c = [5,8,10]

một defference b nên trở c = [0,2,3,4]

ngược a = [10,8,6,5,4,2,0]

Một cái gì đó như thế này.

Cách triển khai phương thức đó trong Java?


Cập nhật: Tôi phải bắt đầu với mẫu này:

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

Một lần nữa, bạn đang nói về các hàm đặt, nhưng bạn sử dụng danh sách. Vì vậy, chức năng chèn của bạn đã sai: Bạn không thử nghiệm cho các bản sao. – Landei

Trả lời

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 cho câu trả lời ngắn gọn. Mặc dù tôi nghĩ rằng bạn có thể đã sử dụng Hashset thay vì ArrayList để lái xe về nhà điểm. – Hari

+0

+1 Nhưng ... Cách tiếp cận này có thể dự trữ thêm không gian, sau đó nó là cần thiết cho kết quả 'Danh sách c'. Có lẽ, sẽ tốt hơn nếu không đặt trước không gian đó trong suốt thời gian tạo mới của ArrayList'? –

+0

@DmytroDzyubak Sự phức tạp của tất cả các phương pháp là bậc hai, thường tồi tệ hơn nhiều so với sử dụng một số không gian không liên quan. Đôi khi nó có thể chấp nhận được, nhưng giải pháp ít nhất cũng đề cập đến nó một cách rõ ràng. – maaartinus

59

Thứ nhất, hoạt động mà bạn mô tả (trừ ngược lại) là thiết lập hoạt động, không liệt kê các hoạt động, vì vậy sử dụng HashSet hoặc (nếu bạn cần đặt hàng) 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

Nếu bạn khai báo 'a' và' b' thành 'NavigableSet', thì bạn có thể đảo ngược thứ tự của chúng bằng phương thức' descendingSet() '. Đối với 'Set' chung, không có khái niệm về thứ tự. – Natix

+0

Câu trả lời hay, mặc dù phần ngược lại là vô nghĩa. Nó có nguồn gốc từ người đứng đầu OP, nhưng bạn không phải làm theo. Hoặc, bạn có thể cung cấp một bộ với bộ so sánh ngược lại. – Vlasec

8

Rất nhiều câu trả lời cho bạn biết sử dụng thư viện mà sẽ làm việc cho bạn. Trong khi đây là giải pháp phù hợp với thế giới thực, hãy nhớ rằng bạn đang làm bài tập ở nhà và giáo viên của bạn có thể muốn bạn hiểu các hàm được viết như thế nào, không chỉ cách tìm thư viện để thực hiện công việc cho bạn.

Điều đó nói rằng, bạn đã có một khởi đầu tốt với mã bạn đã hiển thị. Hãy thực hiện từng bước một vấn đề.

Trước tiên, bạn có biết tài liệu Java nằm ở đâu không? http://download.oracle.com/javase/1.4.2/docs/api/ điều này là rất quan trọng, vì đây là cách bạn tìm ra những chức năng làm những gì. Đây là liên kết đến Java 1.4. Tôi không nhận thấy bạn đang sử dụng phiên bản nào, nhưng Java tương thích ngược, vì vậy điều này là đủ.

Trong tài liệu, hãy tìm mục nhập ArrayList.

Bây giờ chúng tôi đã có tài liệu API, chúng tôi cần chia nhỏ câu hỏi của bạn. bạn đã đăng mã, vì vậy tôi sẽ giải quyết nó theo chức năng.

insert(): bạn có phải có danh sách theo thứ tự hoặc không có trật tự không? Hoặc bạn có chắc chắn rằng các giá trị sẽ được cung cấp cho bạn theo thứ tự? Bạn đã học được các thuật toán sắp xếp chưa?

xóa(): chức năng này không hoạt động. hãy xem API ArrayList và xem cách xóa một mục khỏi danh sách. Sử dụng phương pháp đó.

thành viên(): phương pháp thành viên của bạn không hoạt động. Bạn cần phải kiểm tra mọi mục nhập của danh sách và xác định xem thành viên hiện tại có khớp với đối số hàm hay không. Bạn đã học về vòng lặp chưa?

giao nhau(): ok, cho tôi biết bằng tiếng Anh những gì giao cắt được cho là phải làm.Không sử dụng mô tả của giáo viên nếu bạn có thể giúp - sử dụng các từ của riêng bạn (lưu ý cho người khác, đây là bài tập cho OP để học chương trình, vì vậy xin đừng trả lời nó cho anh ấy)

(): một lần nữa, hãy nói cho tôi bằng tiếng Anh những gì nó phải làm.

đảo ngược(): một lần nữa, hãy cung cấp cho tôi mô tả bằng tiếng Anh về những việc cần làm.

Khi bạn có mô tả bằng tiếng Anh, hãy mô tả thuật toán có thể thực hiện công việc. không viết nó trong Java. chỉ cần viết một thuật toán, bằng tiếng Anh, mô tả cách bạn sẽ làm công việc manaully, với bút và giấy.

tại thời điểm này, hãy thử và chuyển đổi thuật toán thành mã Java.

18

Nếu bạn đang sử dụng Bộ (như bạn nên, cho tất cả những người ngoại trừ ngược lại là Đặt hoạt động), Guava cung cấp các hoạt động này ở lớp Sets.

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

Tất cả các chế độ xem không thể sửa lại này được hỗ trợ bởi Bộ gốc.

Xem Guava Explained ->Collection Utilities ->Sets

Nếu Lists là những gì bạn có, bạn có thể chuyển đổi chúng sang một Set bằng hiện bản sao constructor trong tất cả các bộ sưu tập tiêu chuẩn:

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

đoạn này sẽ tìm thấy sự kết hợp của hai các bộ sưu tập sử dụng phương pháp Collection apache commons commache

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

điều này đã được hỏi sáu năm trước – sbowde4

1

Tôi sẽ để nó ở đây. Có một cách mới với java-8streams

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] 
Các vấn đề liên quan