2011-08-26 56 views
9

Tôi có một danh sách các phần tử (1, 2, 3) và tôi cần lấy danh sách (supetet) của danh sách đó (không lặp lại các phần tử). Vì vậy, về cơ bản tôi cần tạo Danh sách các danh sách trông giống như:In tất cả các tập hợp con có thể có trong danh sách

{1} 
{2} 
{3} 
{1, 2} 
{1, 3} 
{2, 3} 
{1, 2, 3} 

Cách tốt nhất (đơn giản> hiệu quả trong trường hợp này, danh sách sẽ không lớn) để thực hiện điều này? Tốt hơn là trong Java, nhưng một giải pháp trong bất kỳ ngôn ngữ nào sẽ hữu ích.

+1

Bạn muốn tất cả các tập hợp con của danh sách đó. Tôi muốn đề nghị đệ quy. Tuy nhiên, nếu bạn đang xử lý, nói rằng, hơn 30-40 yếu tố, bạn sẽ không thể xử lý HUGE (trên 1TB dữ liệu) mà bạn có. Cái này dùng để làm gì? –

+2

Cấu trúc dữ liệu này bạn đang tìm kiếm được gọi là một Powerset (sự khác biệt là nó cũng chứa một tập rỗng). Nó đã được thảo luận trên SO. –

+0

Cảm ơn Zenzen đã chỉ cho tôi đúng hướng ... Tôi đã tìm thấy http://stackoverflow.com/questions/1670862/obtaining-powerset-of-a-set-in-java. – Steve

Trả lời

31

Sử dụng bitmasks:

int allMasks = (1 << N); 
for (int i = 1; i < allMasks; i++) 
{ 
    for (int j = 0; j < N; j++) 
     if ((i & (1 << j)) > 0) //The j-th element is used 
      System.out.print((j + 1) + " "); 

    System.out.println(); 
} 

Dưới đây là tất cả bitmasks:

1 = 001 = {1} 
2 = 010 = {2} 
3 = 011 = {1, 2} 
4 = 100 = {3} 
5 = 101 = {1, 3} 
6 = 110 = {2, 3} 
7 = 111 = {1, 2, 3} 

Bạn biết trong hệ nhị phân bit đầu tiên là ngoài cùng bên phải.

+0

Điều này là rất thú vị ... bạn rõ ràng là thông minh hơn rất nhiều so với tôi mặc dù - cho tôi một thời gian để bọc tâm trí của tôi xung quanh này .... là N số lượng các yếu tố trong danh sách ban đầu? Và tôi đang lập bản đồ các đối tượng trong danh sách của tôi để số nguyên? – Steve

+0

@Steve - Có, 'N' là số phần tử - trong ví dụ của bạn ở trên' N = 3'. Nghĩ về nhị phân - bit là 0 nếu phần tử không được sử dụng và bit là 1 nếu phần tử được sử dụng. Ví dụ 5 = 101 trong nhị phân. Điều này có nghĩa là '1' và' 3' được sử dụng. '= {1, 3}' –

+0

@Steve - Nhìn vào chỉnh sửa của tôi. –

1
import java.io.*; 
import java.util.*; 
class subsets 
{ 
    static String list[]; 
    public static void process(int n) 
    { 
     int i,j,k; 
     String s=""; 
     displaySubset(s); 
     for(i=0;i<n;i++) 
     { 
      for(j=0;j<n-i;j++) 
      { 
       k=j+i; 
       for(int m=j;m<=k;m++) 
       { 
        s=s+m; 
       } 
       displaySubset(s); 
       s=""; 
      } 
     } 
    } 
    public static void displaySubset(String s) 
    { 
     String set=""; 
     for(int i=0;i<s.length();i++) 
     { 
      String m=""+s.charAt(i); 
      int num=Integer.parseInt(m); 
      if(i==s.length()-1) 
       set=set+list[num]; 
      else 
       set=set+list[num]+","; 
     } 
     set="{"+set+"}"; 
     System.out.println(set); 
    } 
    public static void main() 
    { 
     Scanner sc=new Scanner(System.in); 
     System.out.println("Input ur list"); 
     String slist=sc.nextLine(); 
     int len=slist.length(); 
     slist=slist.substring(1,len-1); 
     StringTokenizer st=new StringTokenizer(slist,","); 
     int n=st.countTokens(); 
     list=new String[n]; 
     for(int i=0;i<n;i++) 
     { 
      list[i]=st.nextToken(); 
     } 
     process(n); 
    } 
} 
+0

Chương trình rất đơn giản. Trước tiên, chúng tôi cố gắng để có được tất cả các kết hợp có thể có của các chữ số 1-n cho đến chữ số cuối cùng của mỗi danh sách 1,2,3, .... n chữ số là n. Và sau đó với mỗi kết hợp để trích xuất từng ký tự của nó (nghĩa là số) và hiển thị phần tử của tập hợp con được lưu trữ trong chỉ mục ô được ký hiệu bằng ký tự này (số). –

+0

Sẽ tốt hơn nếu thêm mô tả mã trong câu trả lời chính nó hơn là trong nhận xét. Câu trả lời với mã chỉ không được coi là câu trả lời hay của cộng đồng nói chung, ngay cả mã trả lời đúng câu hỏi. –

0

Một giải pháp java dựa trên Petar giải pháp Minchev -

public static List<List<Integer>> getAllSubsets(List<Integer> input) { 
    int allMasks = 1 << input.size(); 
    List<List<Integer>> output = new ArrayList<List<Integer>>(); 
    for(int i=0;i<allMasks;i++) { 
     List<Integer> sub = new ArrayList<Integer>(); 
     for(int j=0;j<input.size();j++) { 
      if((i & (1 << j)) > 0) { 
       sub.add(input.get(j)); 
      } 
     } 
     output.add(sub); 
    } 

    return output; 
} 
0

tôi đã nhận thấy rằng câu trả lời đang tập trung vào danh sách String. Do đó, tôi quyết định chia sẻ câu trả lời chung chung hơn. Hy vọng nó sẽ rất hữu ích. (Soultion dựa trên một giải pháp khác mà tôi đã tìm thấy, tôi kết hợp nó với một thuật toán chung chung.)

/** 
* metod returns all the sublists of a given list 
* the method assumes all object are different 
* no matter the type of the list (generics) 
* @param list the list to return all the sublist of 
* @param <T> 
* @return list of the different sublists that can be made from the list object 
*/ 
public static <T> List<List<T>>getAllSubLists(List<T>list) 
{ 
    List<T>subList; 
    List<List<T>>res = new ArrayList<>(); 
    List<List<Integer>> indexes = allSubListIndexes(list.size()); 
    for(List<Integer> subListIndexes:indexes) 
    { 
     subList=new ArrayList<>(); 
     for(int index:subListIndexes) 
      subList.add(list.get(index)); 
     res.add(subList); 
    } 
    return res; 
} 
/** 
* method returns list of list of integers representing the indexes of all the sublists in a N size list 
* @param n the size of the list 
* @return list of list of integers of indexes of the sublist 
*/ 
public static List<List<Integer>> allSubListIndexes(int n) { 
    List<List<Integer>> res = new ArrayList<>(); 
    int allMasks = (1 << n); 
    for (int i = 1; i < allMasks; i++) 
    { 
     res.add(new ArrayList<>()); 
     for (int j = 0; j < n; j++) 
      if ((i & (1 << j)) > 0) 
       res.get(i-1).add(j); 

    } 
    return res; 
} 
Các vấn đề liên quan