2015-06-24 4 views
1

У меня есть многомерный массив, размер которого является динамическим.Комбинированный генератор

String[][] array=new String[][]{{"1","2","3"},{"4","5","6"},{"7","8","9"},{"10","11","12"} }; 

мне нужно генерировать такие комбинации, как, что каждая комбинация длина должна лежит между 1-Array.length и каждой комбинации может иметь максимальную один элемент из строки. если используется столбец из строки, то в этой комбинации не может использоваться другой столбец из этой строки.

, например комбинации с длиной 1 являются:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 

комбинация с длиной 2 являются:

1,4 
1,5 
1,6 
1,7 
1,8 
1,9 
1,10 
1,11 
1,12 

В настоящее время я только смог получить комбинацию с длиной = Array.length, но я требуется длина от 1 до array.length

private String[][] generateCombinations(String[]... arrays) throws Throwable  { 
    if (arrays.length == 0) { 
     return new String[][]{{}}; 
    } 
    int num = 1; 
    for (int i = 0; i < arrays.length; i++) { 
     num *= arrays[i].length; 
    } 

    String[][] result = new String[num][arrays.length]; 
    // array containing the indices of the Strings 
    int[] combination = new int[arrays.length]; 

    for (int i = 0; i < num; i++) { 
     String[] comb = result[i]; 
     // fill array 
     for (int j = 0; j < arrays.length; j++) { 
      comb[j] = arrays[j][combination[j]]; 
     } 

     // generate next combination 
     for (int j = 0; j < arrays.length; j++) { 
      int n = ++combination[j]; 
      if (n >= arrays[j].length) { 
       // "digit" exceeded valid range -> back to 0 and continue incrementing 
       combination[j] = 0; 
      } else { 
       // "digit" still in valid range -> stop 
       break; 
      } 
     } 
    } 
    return result; 
} 
+0

Umm .... вы первый! –

+0

Пожалуйста, напишите, что вы пробовали. – Phoenix

+0

Извините, я не понял ..... что вы хотите сказать ??? –

ответ

1

Нравится ли вам 1 lette r имена переменных ...? : D Я даже не знаю, как это работает сейчас. Он использует бит-маски для нахождения каждой комбинации подмассивов длины n; то он использует некоторую математику мод, чтобы найти каждую комбинацию из 1 из каждого подмассива; то он выплевывает это число. Порядок сортировки не идеален.

public class Perms { 
    private static String[][] array = new String[][] { 
     { "1", "2", "3" }, 
     { "4", "5", "6" }, 
     { "7", "8", "9" }, 
     { "10", "11", "12" } 
    }; 
    private static int combinationLength = 2; 
    public static void main(String[] args) { 
     // Get combinations of subarrays 
     for (int i = 0; i < Math.pow(2, array.length); ++i) { 
      int c = 0; 
      for (int j = 1; j <= Math.pow(2, array.length); j <<= 1) 
       if ((i & j) != 0) 
        ++c; 
      if (c == combinationLength) { 
       String[][] maskedArray = new String[combinationLength][]; 
       for (int l = 1, j = 0, k = 0; l <= Math.pow(2, array.length); l <<= 1, ++j) 
        if ((i & l) != 0) { 
         maskedArray[k] = array[j]; 
         ++k; 
        } 
       // Get combinations of one element per subarray 
       int l = 1; 
       for (int j = 0; j < maskedArray.length; ++j) 
        l *= maskedArray[j].length; 
       for (int j = 0; j < l; ++j) { 
        String s = ""; 
        int m = j; 
        for (int k = maskedArray.length-1; k >= 0; --k) { 
         s = maskedArray[k][m % maskedArray[k].length] + "," + s; 
         m /= maskedArray[k].length; 
        } 
        // Spit out a result 
        System.out.println(s.substring(0, s.length()-1)); 
       } 
      } 
     } 
    } 
} 
+0

Нет, это только комбинация поколений с длиной 2 –

+1

le variable: 'private static int combinationLength = 2;' – Luke

+0

Спасибо Luke, я изменил этот код в соответствии с моим требованием, и он работает нормально, но имеет проблемы с временной сложностью, но я их разрешу , Еще раз спасибо. :) –

0

Хорошо, если я получаю то, что вы просите, тогда позвольте мне уточнить.

Вам нужна вся комбинация некоторых n наборов, где в любой комбинации вы можете взять только один элемент из одного набора. И длина комбинации может быть от 1 до n.

Так что в основном это алгоритм, который будет работать.

  1. У каждого комплекта есть опция, которая может быть либо в комбинации, либо может быть не в комбинации.
  2. И если какой-либо набор находится в комбинации, он имеет p опций (p - длина набора), чтобы выбрать любой из его элементов.

Поэтому в основном мы получаем (2^arraylength -1 (не принято)) * (P) P = число элементов в каждом наборе этих многочисленных комбинаций.

Так что в основном то, что вы делаете, это написать рекурсивную функцию, чтобы дать ей параметры типа level, len.

Напишите цикл for, чтобы len переходил от 1 до n; теперь для каждого значения i [1, len] рекурсивная функция будет печатать всю комбинацию в порядке длины len.

Таким образом, вы получите всю комбинацию длины 1 в arraylength() Это код, который я написал, но он не выполним, но это более понятная версия моего алгоритма.

Так вот что вы можете сделать.

int main() 
{ 
    string s=" "; 
    for(int i=0;i<=array.length;++i) 
    { 
     print-recur(array,s,arra.length,i,3,0); 
    } 
    return 0; 
} 

void print-recur(string array[][],string s[],int arlen,int len,int p,int level) 
{ 
    if(level>aralen) 
    return ; 
    else 
    { 
     if(len>0) 
    { 
     //this is not taking this level 
     if(len>aralen-level) 
     print-recur(a,s,arlen,len,p,level+1); 
     //the for loop is when the level is in the combination 
     for(i=0;i<p;++i) 
     { 
      s+=array[level][i]; 
      print-recur(a,s,arlen,len-1,p,level+1); 
      str.erase(str.end()-1); 
     } 
    } 
     else 
    cout<<s<<endl; 
    } 
} 
+0

В вашей программе слишком много синтаксических ошибок, а также проблемы с именами переменных. –

+0

Я имею в виду, что я написал код только для объяснения алгоритма. – Anup

+0

Ok Anup Спасибо за ваши усилия. –

0

Если кто-то ищет более гибкое решение, я создаю его с использованием потока и уменьшаю. Вы можете видеть, что он работает здесь https://ideone.com/sSRrY3.

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import java.util.stream.Collectors; 

class Combination { 
    private List<List<List<String>>> pairs = new ArrayList<>(); 

    public Combination(List<String> elements) { 
     this.pairs = createPairsFromElements(elements); 
    } 

    private Combination() { 
    } 

    public static Combination createFromPairs(String[][] arrPairs) { 
     Combination combination = new Combination(); 
     combination.pairs = createPairsFromArrayPairs(arrPairs); 
     return combination; 
    } 

    /** 
    * Create the pairs based on the String[][] 
    * 
    * Add the empty option at the beginner of each group 
    * Create the Lists and group them again 
    * 
    * @param arrPairs 
    * @return pairs 
    */ 
    private static List<List<List<String>>> createPairsFromArrayPairs(String[][] arrPairs) { 
     List<List<List<String>>> pairs = new ArrayList<>(); 

     for (String[] groupValue: arrPairs) { 

      List<List<String>> listGroupValue = new ArrayList<>(); 

      /* add the empty value to the pairs */ 
      listGroupValue.add(Arrays.asList()); 

      for (String value: groupValue) { 

       List<String> listValue = Arrays.asList(value); 
       listGroupValue.add(listValue); 

      } 

      pairs.add(listGroupValue); 
     } 
     return pairs; 

    } 

    /** 
    * Convert the string list "a", "b", "c" to 
    * this: 
    * [ 
    * [ [], [a] ], [ [], [b] ], [ [], [c] ] 
    * ] 
    * 
    * @param elements List of values to the collection 
    * @return pairs 
    */ 
    private static List<List<List<String>>> createPairsFromElements(List<String> elements) { 
     return elements.stream().map(
       (String value) -> { 
        List<List<String>> values = Arrays.asList(
          Arrays.asList(),   // immutable empty list 
          Arrays.asList(value)  // immutable atomic list 
        ); 
        return values; 
       } 
     ).collect(Collectors.toList()); 
    } 

    /** 
    * Get the combination without restriction 
    * 
    * @param size 
    * @return 
    */ 
    public List<List<String>> getCombination(int size) { 
     return this.getCombination(size, false); 
    } 

    /** 
    /* 
    * Combine every pair of elements creating a big list 
    * [ [], [b] ] x [ [], [a] ] = [ ([] + []), ([] + [a]), ([b] + []), ([b] + [a])) ] = 
    * [ [], [a], [b], [a, b] ] 
    * This keep working until add all elements. 
    * 
    * We filter to remove the combinations that are bigger than the max size 
    * 
    * @param size Max size of each result list 
    * @param restricted Should be exactly the received size. 
    * @return List of combinations 
    */ 
    public List<List<String>> getCombination(int size, boolean restricted) { 

     List<List<String>> result = pairs.parallelStream().reduce(
      new ArrayList<>(), 
      (acc,current) -> { 
       if(acc.size() == 0) { 
        return current; 
       } 

       List<List<String>> combinations = new ArrayList<>(); 

       current.stream().forEach(
        (List<String> valueCurrent) -> acc.stream().forEach(
         (List<String> valueAcc) -> { 
          List<String> combination = new ArrayList<>(); 
          combination.addAll(valueAcc); 
          combination.addAll(valueCurrent); 
          if(combination.size() <= size) { 
           combinations.add(combination); 
          } 
         } 
        ) 
       ); 
       return combinations; 
      } 
     ); 

     if(! restricted) { 
      return result; 
     } 

     /* if the combination is size restricted, filter only elements with the exactly size */ 
     return result.stream().filter(combination -> combination.size() == size). 
       collect(Collectors.toList()); 
    } 
} 

public class Main { 

    public static void main(String[] param) { 

     Combination combination = new Combination(Arrays.asList("A","B","C","D","E")); 

     /* show all the combinations from 0 to 3 elements */ 
     System.out.println(combination.getCombination(3)); 
     // [ 
     // [], 
     // [A], 
     // [B], [A, B], 
     // [C], [A, C], [B, C], [A, B, C], 
     // [D], [A, D], [B, D], [A, B, D], [C, D], [A, C, D], [B, C, D], 
     // [E], [A, E], [B, E], [A, B, E], [C, E], [A, C, E], [B, C, E], [D, E], [A, D, E], [B, D, E], [C, D, E] 
     // ] 

     /* show all the combinations with exactly 4 elements */ 
     System.out.println(combination.getCombination(4, true)); 
     // [ 
     // [A, B, C, D], 
     // [A, B, C, E], 
     // [A, B, D, E], 
     // [A, C, D, E], 
     // [B, C, D, E] 
     // ] 

     Combination other = Combination.createFromPairs(
       new String[][]{{"1","2","3"},{"4","5","6"},{"7","8","9"},{"10","11","12"} } 
     ); 

     /* show all the combinations with exactly 3 elements */ 
     System.out.println(other.getCombination(3, true)); 
     // [ 
     // [1, 4, 7], [2, 4, 7], [3, 4, 7], [1, 5, 7] ... 
     // ... [3, 9, 12], [4, 9, 12], [5, 9, 12], [6, 9, 12] 
     // ] 

    } 
}