如何迭代每个独立选择的排列?

时间:2014-09-14 02:27:11

标签: java algorithm recursion

假设我有一个列表[x1, x2, x3]x1x2x3可以使用1到5之间的任何值。

我想迭代可以创建的每个可能列表(从[1, 1, 1][1, 1, 2] ,.到[5, 5, 5])。这是一个简单的问题,列表中只有3个元素。

您可以这样做:

for x = 1; x <= 5; x++;
    for y = 1; y <= 5; y++;
        ...
          for q = 1; q <= 5; q++;
              create list [x, y, ..., q];
              do something with the list;

但是,如何迭代每个可能的列表,其中元素的数量超过10?

Edi:我已经添加了Java作为约束。我只是想看看如果没有太多花哨的库调用就可以完成这项工作。

Edit2:我真正想要的是一些算法来做到这一点,而不是可以用什么类型的库来做到这一点。但我正在寻找的是一种与语言无关的算法。

6 个答案:

答案 0 :(得分:2)

使用Guava,您可以轻松完成:

     public static void main(String[] args) {

         int lowerBound = 1;
         int upperBound = 5;
         int setSize=3;

         ContiguousSet<Integer> integers = ContiguousSet.create(Range.closed(lowerBound, upperBound), DiscreteDomain.integers());
         List<Set<Integer>> sets = Lists.newArrayList();

         for (int i = 0; i < setSize; i++) {
             sets.add(integers);
         }

         Set<List<Integer>> cartesianProduct = Sets.cartesianProduct(sets);
         for (List<Integer> list : cartesianProduct) {
             System.out.println(list);
         }
     }

打印哪些:

[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
[1, 1, 4]
[1, 1, 5]
...  
[5, 5, 4]
[5, 5, 5]

答案 1 :(得分:1)

至少在python中(如果是约束,则应指定语言):

>>> from itertools import permutations as permu
>>> for i in permu(range(5), 3):
...     print i 
... 
(0, 1, 2)
(0, 1, 3)
(0, 1, 4)
(0, 2, 1)
(0, 2, 3)
(0, 2, 4)
(0, 3, 1)
....

答案 2 :(得分:1)

在递归解决方案中,您不必每次都对列表​​进行排序。将排序列表赋予递归函数必须是有效的 为此,我编写了这段C#代码。输出结果的长度将由len确定。请记住输入长度必须等于或大于len:

// Input must be sorted, Result must be initialized to empty list
void Iterate(List<int> input, int len, List<int> result)
{
  if(result.Count == n)
    print result
  else
    foreach (var i in input)
      Iterate(input, len, result.Append(num).ToList())
}

答案 3 :(得分:1)

使用此算法。

输入:X是最小数字,Y是最大数字,Z是独立选择的数量。

  • 创建一个大小为Z的数组,每个元素等于X.将其命名为Permutation。
  • 循环:
    • 将Permutation的副本添加到排列列表中。
    • 将J设为Z减1。
    • 循环:
      • 将1添加到置换[J]。如果排列[J]现在是Y或更小,请休息。
      • 设置排列[J]至X。
      • 从J.减去1如果J现在小于0,则返回排列列表。

答案 4 :(得分:0)

必须是经典算法。但是从头开始编写它总是很有趣。这是接受数据集和结果列表大小参数的Java类。核心方法是generate()。也可以按需复制列表(更具功能性)。

import com.google.common.collect.Maps;
import org.apache.commons.lang.ArrayUtils;

import java.util.Map;

public class PermutationGenerator {

    private int listValuesSize;

    private int resultListSize;

    private String[] currentList;

    private Map<String, String> nextValue = Maps.newHashMap();

    private int permutations = 0;

    public PermutationGenerator(String[] dataSet, int resultListSize) {
        this.listValuesSize = dataSet.length;
        this.resultListSize = resultListSize;
        init(dataSet);
    }

    private void init(String[] dataSet) {

        // rolling values
        String previous = dataSet[0];
        for (int valuesIndex = 1; valuesIndex < dataSet.length; valuesIndex++) {
            nextValue.put(previous, dataSet[valuesIndex]);
            previous = dataSet[valuesIndex];
        }
        nextValue.put(dataSet[dataSet.length - 1], dataSet[0]);

        // init
        currentList = new String[resultListSize];
        for (int i = 0; i < resultListSize; i++) {
            currentList[i] = dataSet[0];
        }
    }

    public void generate() {
        generate(0, resultListSize - 1);
    }

    private void generate(int from, int to) {
        if (from > to) {
            return;
        }

        for (int i = 0; i < listValuesSize; i++) {
            if (from == to) {
                processList(currentList);
            } else {
                generate(from + 1, to);
            }
            roll(from);
        }
    }

    private void roll(int position) {
        currentList[position] = nextValue.get(currentList[position]);
    }

    private void processList(String[] list) {
        permutations++;
        System.out.println(ArrayUtils.toString(list));
    }

    public static void main(String... args) {
        PermutationGenerator generator = new PermutationGenerator(new String[]{"1", "2", "3", "4", "5"}, 3);
        generator.generate();
        System.out.println(generator.permutations);
    }

}

答案 5 :(得分:0)

逻辑: 在arr [x1 x2 x3];所有x1,x2,x3的值都可以是1到5.这意味着数组中的每个位置都可以具有1到5的值。对于当前位置的值,所有值都可以在下一个位置。

假设存储的数组值的0位置为1。

[1 _ _] _表示没有价值。

下一个位置的值:[1 1 _],[1 2 _],[1 3 _],[1 3 _],[1 4 _],[1 5 _]。

因此迭代当前位置以在当前位置存储1到5的不同可能值,并且对于每个值,再次调用置换函数,当前位置值递增1,以便在下一个位置迭代从1到5的所有可能值。

代码:

public class permutation {

    static int limit;
    public static void permutate(int arr[],int curPos)
    {
        int i;
        if(curPos==arr.length)
        {
            for(i=0;i<arr.length;i++)
            {
                System.out.print(arr[i] + "\t");
            }
            System.out.println("");
            return;
        }

        for(i=1;i<=limit;i++)
        {
            arr[curPos]=i;
            permutate(arr,curPos+1);
        }  

    }


    public static void main(String[] args) {
        int arr[] = new int[3];
        limit = 5;
        permutate(arr,0);
    }

}

输出

1   1   1   
1   1   2   
1   1   3   
1   1   4   
1   1   5   
1   2   1   
1   2   2   
1   2   3   
1   2   4   
1   2   5   
1   3   1   
1   3   2   
1   3   3   
1   3   4   
1   3   5   
1   4   1   
1   4   2   
1   4   3   
1   4   4   
1   4   5   
1   5   1   
1   5   2   
1   5   3   
1   5   4   
1   5   5   
2   1   1   
2   1   2   
2   1   3   
2   1   4   
2   1   5   
2   2   1   
2   2   2   
2   2   3   
2   2   4   
2   2   5   
2   3   1   
2   3   2   
2   3   3   
2   3   4   
2   3   5   
2   4   1   
2   4   2   
2   4   3   
2   4   4   
2   4   5   
2   5   1   
2   5   2   
2   5   3   
2   5   4   
2   5   5   
3   1   1   
3   1   2   
3   1   3   
3   1   4   
3   1   5   
3   2   1   
3   2   2   
3   2   3   
3   2   4   
3   2   5   
3   3   1   
3   3   2   
3   3   3   
3   3   4   
3   3   5   
3   4   1   
3   4   2   
3   4   3   
3   4   4   
3   4   5   
3   5   1   
3   5   2   
3   5   3   
3   5   4   
3   5   5   
4   1   1   
4   1   2   
4   1   3   
4   1   4   
4   1   5   
4   2   1   
4   2   2   
4   2   3   
4   2   4   
4   2   5   
4   3   1   
4   3   2   
4   3   3   
4   3   4   
4   3   5   
4   4   1   
4   4   2   
4   4   3   
4   4   4   
4   4   5   
4   5   1   
4   5   2   
4   5   3   
4   5   4   
4   5   5   
5   1   1   
5   1   2   
5   1   3   
5   1   4   
5   1   5   
5   2   1   
5   2   2   
5   2   3   
5   2   4   
5   2   5   
5   3   1   
5   3   2   
5   3   3   
5   3   4   
5   3   5   
5   4   1   
5   4   2   
5   4   3   
5   4   4   
5   4   5   
5   5   1   
5   5   2   
5   5   3   
5   5   4   
5   5   5