2017-07-06 142 views
-1

我有一個對象列表M := [A, B, C, ... Z],我想創建一個新列表N,其中包含非重複固定大小「f」這些對象的排列。創建固定大小元素列表中的非重複排列列表

因此n將(for f = 2) [[A, B], [A, C], ...],但不應該包含類似[A, A]重複,如果[A, B]設置[B, A]應該被忽略。

我發現事情好像GuavasPowerSet」,但是這不會幫助我,因爲它不能被「裁剪」爲固定大小。

我希望我已經正確地指出我的問題。

˚F應該始終是以下2

基於http://algorithms.tutorialhorizon.com/print-all-combinations-of-subset-of-size-k-from-given-array/我所做的:

private Set<List<Object>> combineObjects(List<Object> M) { 
    boolean[] used = new boolean[M.size()]; 
    return generateObjectCombinations(M, 0, 0, used); 
} 

private Set<List<Object>> generateObjectCombinations(
    List<Object> M, 
    int start, 
    int curLen, 
    boolean[] used 
) { 
    Set<List<Object>> returnSet = new HashSet<>(); 
    if (curLen == 2) { 
     List<Object> data = newArrayList(); 
     for (int i = 0; i < M.size(); i++) { 
      if (used[i]) { 
       data.add(M.get(i)); 
      } 
     } 
     returnSet.add(data); 
     return returnSet; 
    } 
    if (start == M.size()) { 
     return Collections.emptySet(); 
    } 
    used[start] = true; 
    returnSet.addAll(generateObjectCombinations(M, start + 1, curLen + 1, used)); 
    used[start] = false; 
    returnSet.addAll(generateObjectCombinations(M, start + 1, curLen, used)); 
    return returnSet; 
} 

這是工作,但我不知道是否有一個「乾淨」的解決方案。我想消除布爾數組。

不,這不是我的功課。也許我只是很累,應該休假。

編輯 基於@ azro的回答我重組這樣的代碼:

List<List<Object>> combinations = new ArrayList<>(); 
List<Object> M = new ArrayList<>(); 

for (int i = 0; i < M.size(); i++) { 
    Object outerM = M.get(i); 

    for (int j = i; j < M.size(); j++) { 
     Object innerM = M.get(j); 
     if (innerM.equals(outerM)) { 
      continue; 
     } 
     combinations.add(Lists.newArrayList(outerM, innerM)); 
    } 
} 

甚至更​​好

List<List<Object>> combinations = new ArrayList<>(); 
List<Object> M = new ArrayList<>(); 

for (int i = 0; i < M.size(); i++) { 
    Object outerM = M.get(i); 

    for (int j = (i + 1); j < M.size(); j++) { 
     Object innerM = M.get(j); 
     combinations.add(Lists.newArrayList(outerM, innerM)); 
    } 
} 

我真的應該採取過長...度假。謝謝@azro!

+0

不是真的 - 你有什麼問題嗎? –

+0

顯示一些事情,你已經做了但 – azro

+0

我知道你的意思。這很簡單..你需要的只是在Foreach循環中有字母的數組和Foreach循環。 – Bernhard

回答

1

由於您沒有寫「F應該總是2」開始的時候我寫了工程f>=1,所以這裏的方法和如何使用它的解決方案:

public static void main(String[] args) { 
     List<String> letter = Arrays.asList("A", "B", "C", "D", "E"); 
     List<String> res = new ArrayList<>(); 
     res.addAll(letter); 
     int size = 2; 

     for (int i = 1; i < size ; i++) { 
      res = addLetter(res, letter); //add a letter to all 
     } 

     res.forEach(p -> System.out.println(p)); 
} 

public static List<String> addLetter(List<String> already, List<String> letters) { 
    List<String> res = new ArrayList<>(); 

    for (String al : already) { 
     for (String let : letters) { 
      if (!al.contains(let)) { 
       res.add(al + let); 
      } 
     } 
    } 
    return res; 
} 

如果「F應該總是2」你只需要:

public static void main(String[] args) { 
    List<String> letters = Arrays.asList("A", "B", "C", "D", "E"); 
    List<String> res = new ArrayList<>(); 

    for (String al : letters) { 
     for (String let : letters) { 
      if (!al.contains(let)) { 
       res.add(al + let); 
      } 
     } 
    } 
    res.forEach(p -> System.out.println(p)); 
} 
+0

感謝@azro。 –

0

我不知道這是否是最好的解決辦法,但你在這裏:

static HashSet<HashSet<String>> getCombinations(HashSet<HashSet<String>> s, int f) 
{ 
    if(f == 1) 
     return s; 
    HashSet<HashSet<String>> newSet = new HashSet<HashSet<String>>(); 
    for (HashSet<String> ss : s) 
    { 
     for(String elm : A) 
     { 
      if(ss.contains(elm)) 
       continue; 
      HashSet<String> sss = (HashSet<String>)ss.clone(); 
      sss.add(elm); 
      newSet.add(sss); 
     } 
    } 
    return getCombinations(newSet, f-1); 
} 

用法:

String[] A = {"A", "B", "C", "D", "E"}; 
public static void main(String[] args) 
{ 
    int f = 3; 
    HashSet<HashSet<String>> set = new HashSet<>(); 
    for(String s : A) 
    { 
     HashSet<String> ss = new HashSet<>(); 
     ss.add(s); 
     set.add(ss); 
    } 
    System.out.println(getCombinations(set, f)); 
}