2011-08-26 27 views
9

Öğelerim listesi (1, 2, 3) var ve bu listenin üst kümesi (powerset) (yinelenen öğeler olmadan) almam gerekiyor. Böylece temelde benziyor Listelerinin bir listesi oluşturmanız gerekir:Bir listenin olası tüm alt kümelerini yazdırma

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

iyi nedir bu uygulamaya yol (bu durumda basitlik> verimliliği, liste çok büyük olmayacak)? Tercihen Java'da, ancak herhangi bir dilde bir çözüm yararlı olacaktır.

+1

Bir liste tüm alt kümelerini istiyorum. Özyinelemeyi öneririm. Bununla birlikte, 30-40'tan fazla elemanla uğraşırsanız, sahip olduğunuz BÜYÜK (1TB'den fazla veri) ile uğraşamayacaksınız. Bu ne için kullanılır? –

+2

Aradığınız bu veri yapısı bir Powerset (farklı bir boş kümeyi de içerir) olarak adlandırılır. SO üzerinde zaten tartışıldı. –

+0

Beni doğru yönde işaret ettiğin için teşekkürler Zenzen ... http://stackoverflow.com/questions/1670862/obtaining-powerset-of-a-set-in-java bulundu. – Steve

cevap

31

Kullanım bit maskesi:

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} 

Sen ikili ilk bit en sağdaki olduğunu biliyoruz:

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(); 
} 

İşte bütün değerleri bir bit maskesi vardır. Petar Minchev çözüme dayalı

+0

Bu çok enteresan ... açıkçası benden çok daha akıllısın - zihnimi bunun etrafına sarmak için biraz zaman ver ... N orijinal listede bulunan elemanların sayısı nedir? Ve listemdeki nesneleri tamsayılarla mı eşleştiriyorum? – Steve

+0

@Steve - Evet, 'N' öğelerin sayısıdır - yukarıdaki örnekte 'N = 3'. İkili düşünün - eğer eleman kullanılmazsa bit 0'dır ve eğer eleman kullanılırsa bit 1'dir. Örneğin ikilide 5 = 101. Bu '1' ve' 3' kullanılır. '= {1, 3}' –

+0

@Steve - Düzenlememe bak. –

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

Program basit. İlk olarak, 1 n. N basamaklı sayıların tüm olası kombinasyonlarını 1,2,3, ... n haneli sayı n'nin son hanesine kadar elde etmeye çalışıyoruz. Ve sonra her bir kombinasyonun karakterinin her birini (yani sayı) çıkarması ve bu karakterle (sayı) belirtilen hücre indeksinde saklanan alt kümenin elemanını göstermesi. –

+0

Kodun açıklamasını, yorumlardakinden daha iyi bir şekilde eklemek daha iyi olurdu. Kod ile cevap sadece genel olarak toplum tarafından iyi bir cevap olarak kabul edilmez, hatta kod düzgün bir şekilde soruya cevap verir. –

0

bir java çözümü - cevaplar dize listesinde odaklı olduğunu fark ettim

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

. Sonuç olarak, daha genel bir cevabı paylaşmaya karar verdim. Umarım yararlı olur. (Soultion buldum başka çözümlere dayanmaktadır, ben genel algorithem bunu birleştirdi.)

/** 
* 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; 
} 
İlgili konular