【问题标题】:Order array in every possible sequence [duplicate]以每个可能的顺序排列数组[重复]
【发布时间】:2012-12-17 11:01:21
【问题描述】:

我有一些复杂的计算算法,基本上可以测试一些较小的矩阵是否适合另一个大矩阵。
如果所有小矩阵都适合大矩阵,则取决于较小矩阵的顺序。 如果小矩阵不适合,它应该重新排列 ArrayList 并重试,直到测试所有可能的顺序/序列。

如果我有 5 个小矩阵,那么总共有 5 个! (= 120) 数组可以有的可能顺序。

我的问题是我不知道如何重新排列这些对象(矩阵),所以我可以测试每个可能的顺序。我希望有人可以帮助我吗?

【问题讨论】:

标签: java arrays


【解决方案1】:

对于n 对象,有n! 排列。考虑一个集合:

S = {a1, a2, a3 ..., an};

找到上述集合的排列的算法可能是:

foreach(item i : S) {
   /* all other item except i1 and i */
   foreach(item i1 : S - {i}) {
       foreach(item i2 : S - {i, i1}) {
          .
          .
          .
          foreach(item in : S - {i, i2, .... in-1}) {
             /* permutation list */
             P = { i1, i2, ...., in-1, in }; 
          }
       }
   }
}

显然我们不能有nfor 循环,但我们可以递归地构造这个算法,直到我们在列表P 中得到n 元素。下面是使用上述算法进行排列的实际 java 代码:

public static void 
permutations(Set<Integer> items, Stack<Integer> permutation, int size) {

    /* permutation stack has become equal to size that we require */
    if(permutation.size() == size) {
        /* print the permutation */
        System.out.println(Arrays.toString(permutation.toArray(new Integer[0])));
    }

    /* items available for permutation */
    Integer[] availableItems = items.toArray(new Integer[0]);
    for(Integer i : availableItems) {
        /* add current item */
        permutation.push(i);

        /* remove item from available item set */
        items.remove(i);

        /* pass it on for next permutation */
        permutations(items, permutation, size);

        /* pop and put the removed item back */
        items.add(permutation.pop());
    }
}

这里是主要方法:

public static void main(String[] args) {
    // TODO Auto-generated method stub


    Set<Integer> s = new HashSet<Integer>();
    s.add(1);
    s.add(2);
    s.add(3);

    permutations(s, new Stack<Integer>(), s.size());
}

它打印了结果:

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]

【讨论】:

    【解决方案2】:

    如果您使用的是 Java > 8,则有一个更智能的解决方案:

    static Stream<List<Integer>> permutations(List<Integer> input) {
        if (input.size() == 1) {
            return Stream.of(new LinkedList<>(input));
        }
        return input.stream()
                .flatMap(first -> permutations(input.stream()
                   .filter(a -> !a.equals(first))
                   .toList())
                .map(LinkedList::new)
                .peek(l -> l.addFirst(first)));
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-05
      • 1970-01-01
      • 2012-02-14
      • 2012-07-06
      • 1970-01-01
      • 2020-02-22
      • 2017-10-14
      • 1970-01-01
      • 2016-11-17
      相关资源
      最近更新 更多