从Java中的列表创建不同的排列

时间:2015-04-11 06:28:55

标签: java list recursion permutation

好,

我需要一些帮助来弄清楚我是如何做到这一点的。

我有一个对象1-i的子列表A-n的主列表,如下所示:

M{A(1, 2, 3, ... i),
B(1, 2, 3, ... i),
C(1, 2, 3, ... i), ... ,
n(1, 2, 3, ... i)}

我想从中得到的是这个的所有不同排列的列表,但我不知道子列表中有多少项,或者那些对象有多少。

所以对象1 - i中有一个我不想重叠的属性。我需要列出所有可能的排列。每个子列表中的一个对象。 EX:

All{
1{A.1, B.1, C.1 N.1},
2{A.1, B.1, C.1 N.2},
3{A.1, B.1, C.1 N.3},
...
{A.1, B.1, C.1 N.i},
{A.1, B.1, C.2 N.1},
{A.1, B.1, C.2 N.2},
{A.1, B.1, C.2 N.3},
...
{A.1, B.1, C.2 N.i},
{A.1, B.2, C.1 N.1},
{A.1, B.2, C.1 N.2},
{A.1, B.2, C.1 N.3},
...
{A.1, B.2, C.1 N.i},
...
...
...
{A.i, B.i, C.i N.i}}

我一直在尝试用Java的递归方式来做这个,但我不知道怎么弄清楚,因为我不知道任何列表的计数,并且它们每次都可以改变然

2 个答案:

答案 0 :(得分:2)

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Main
{
    private static String [][] inputList = 
    {
        {"A1","A2","A3","A4"},
        {"B1","B2","B3","B4"},
        {"C1","C2","C3","C4"},
    };
    private static int listSize = 4;
    private static List<List<String>> lists = new ArrayList<List<String>>();

    public static void permutation(List<Integer> indexes, int size)
    {
        if(checkEnd(indexes, size))
        {
            return;
        }
        List<String> nextList = new ArrayList<String>();
        int rowIndex = 0;
        for(int i : indexes)
        {
            nextList.add(inputList[rowIndex++][i]);
        }
        lists.add(nextList);
        permutation(nextIndexes(indexes, size),size);
    }

    public static boolean checkEnd(List<Integer> indexes, int size)
    {
        for(int i : indexes)
        {
            if(i < (size - 1))
            {
                return false;
            }
        }
        return true;
    }

    public static List<Integer> nextIndexes(List<Integer> indexes, int size)
    {
        Collections.reverse(indexes);
        for(int index = 0; index < indexes.size(); index++)
        {
            if(indexes.get(index) < (size - 1))
            {
                indexes.set(index, indexes.get(index) + 1);
                break;
            }
        } 
        Collections.reverse(indexes);
        return indexes;
    }

    public static void printList(List<String> list)
    {
        StringBuilder builder = new StringBuilder();
        builder.append("{");
        for(String field : list)
        {
            builder.append(field);
            builder.append(",");
        }
        builder.deleteCharAt(builder.length()-1);
        builder.append("}");
        System.out.println(builder.toString());
    }

    public static void main(String[] args)
    {
        List<Integer> indexes = new ArrayList<Integer>();
        for(int i = 0; i < inputList.length; i++)
        {
            indexes.add(0);
        }
        permutation(indexes, listSize);
        for(List<String> list : lists)
        {
            printList(list);
        }
    }
}

答案 1 :(得分:0)

这是一个非常简单的迭代方法:将每个排列表示为p整数的数组K,表示列表A .. n的索引。每个K元素p[k]的范围均为0到S[k]-1,其中S[k]是列表k的长度。

给定一个排列p i ,你可以通过“递增”你的数组来构造排列p i + 1 ,就像你增加一个整数一样p[k]是“数字”:

  • 以全零置换开始
  • 在每次迭代中,通过递增p[0]
  • 来增加排列
  • 如果p[0]小于S[0],则递增完成;继续下一个排列
  • 否则,请将p[0]设置为零,然后增加p[1]
  • 如果p[1]小于S[1],则递增完成;继续下一个排列
  • 否则,请将p[1]设置为零,然后增加p[2]
  • 继续,直到您到达最后一个索引p[K-1]
  • 如果将p[K-1]设置为零,则完成循环。

给定索引数组,构造实际列表元素的排列是微不足道的。请注意,排列的数量可以非常快,所以要非常小心地将它们存储在内存中。