Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归生成列表的所有可能排列_Java_Algorithm_Permutation - Fatal编程技术网

Java 递归生成列表的所有可能排列

Java 递归生成列表的所有可能排列,java,algorithm,permutation,Java,Algorithm,Permutation,我试图递归地生成列表中的所有项。对于类似的问题,我已经看到了一些解决方案,但我一直无法让我的代码正常工作。有人能指出我如何修复代码吗 这对所有S/O开放,而不仅仅是Java用户 (我还应该注意,它崩溃时出现了一个SO异常) 样本输入: [1,2,3] 输出: [1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3,2,1] //allPossibleItems is an AL of all items //this is called wi

我试图递归地生成列表中的所有项。对于类似的问题,我已经看到了一些解决方案,但我一直无法让我的代码正常工作。有人能指出我如何修复代码吗

这对所有S/O开放,而不仅仅是Java用户

(我还应该注意,它崩溃时出现了一个SO异常)

样本输入: [1,2,3]

输出: [1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3,2,1]

//allPossibleItems is an AL of all items 

//this is called with generatePerm(null, new ArrayList<Item>);

private void generatePerm(Item i, ArrayList<Item> a) {
      if(i != null) { a.add(i); }
      if (a.size() == DESIRED_SIZE){
          permutations.add(a);
          return;
      }
      for(int j = 0; j < allPossibleItems.size(); j ++) {
          if(allPossibleItems.get(j) != i)
            generatePerm(allPossibleItems.get(j), a);
      }
  }
//allPossibleItems是所有项目的AL
//这是用generatePerm(null,newArrayList)调用的;
专用无效生成项(项目i,ArrayList a){
如果(i!=null){a.add(i);}
如果(a.size()==所需的大小){
加入(a);
返回;
}
对于(int j=0;j
问题在于,在进行递归调用之前,必须先查看ArrayList。否则,将始终添加到同一ArrayList

//allPossibleItems is an AL of all items 

//this is called with generatePerm(null, new ArrayList<Item>);

private void generatePerm(Item i, ArrayList<Item> a) {
      if(i != null) { a.add(i); }
      if (a.size() == DESIRED_SIZE){
          permutations.add(a);
          return;
      }
      for(int j = 0; j < allPossibleItems.size(); j ++) {
          if(!a.contains(allPossibleItems.get(j))){
            ArrayList<Item> b = clone(a);
            generatePerm(allPossibleItems.get(j), b);
          }
      }
  }
//allPossibleItems是所有项目的AL
//这是用generatePerm(null,newArrayList)调用的;
专用无效生成项(项目i,ArrayList a){
如果(i!=null){a.add(i);}
如果(a.size()==所需的大小){
加入(a);
返回;
}
对于(int j=0;j
如果
所有可能项
包含两个不同的元素,x和y,那么您将依次将x和y写入列表,直到它达到
所需的大小。这就是你真正想要的吗?如果选择足够大的
所需的\u SIZE
,堆栈上将有太多递归调用,因此会出现SO异常

我要做的是(如果原件没有重复件/副本):

public List generatePerm(列表原件){
if(original.isEmpty()){
列表结果=新建ArrayList();
添加(新的ArrayList());
返回结果;
}
E firstElement=原始。删除(0);
List returnValue=new ArrayList();
列表置换=生成项(原始);
对于(列表smallermutated:permutations){

对于(int-index=0;index谷歌搜索让我想到了这个问题。我发现下面的方法比其他方法更快

基本上,我使用一个集合递归地生成排列。举例来说,第一个位置可以容纳所有可能的值,第二个位置可以容纳除第一个值以外的所有可能的值,依此类推。当我们到达最后一个位置时,只有一种可能性

就递归函数的参数而言,(1)我们传递已经记录为currentstring的内容。(2)我们传递Arraylist,它保存结果-列表\u的\u permutes(3)我们传递从中选择当前数字的集合-currentnums。 在最后一级,我们有一个完整的置换,然后将其添加到arraylist-list\u of_置换中,并向上返回

public static ArrayList recurse_nums(Set<Integer> currentnums, String currentstring, ArrayList list_of_permutes){
    if(currentnums.size()==1){
        int elem = currentnums.iterator().next();
        list_of_permutes.add(currentstring + Integer.toString(elem));
        return list_of_permutes;
    }
    for(int a:currentnums){
        String newstring = currentstring + a;
        Set<Integer> newnums = new HashSet<>();
        newnums.addAll(currentnums);
        newnums.remove(a);
        recurse_nums(newnums, newstring,list_of_permutes);
    }
    return list_of_permutes;
}
public static ArrayList recurse\u nums(Set currentnums,String currentstring,ArrayList list\u of_permutes){
如果(currentnums.size()==1){
int elem=currentnums.iterator().next();
添加(currentstring+Integer.toString(elem));
返回列表\u的\u permutes;
}
用于(int a:currentnums){
字符串newstring=currentstring+a;
Set newnums=newhashset();
newnums.addAll(当前nums);
删除(a);
递归(newnums、newstring、排列列表);
}
返回列表\u的\u permutes;
}
这可以通过以下方式调用:

public static ArrayList permute_array(int[] arr){
    Set<Integer> currentnums = new HashSet<>();
    for (int i = 0; i < arr.length; i++) {currentnums.add(arr[i]);}
    ArrayList permutations = new ArrayList();
    recurse_nums(currentnums,"",permutations);
    return permutations;
}
公共静态数组列表置换数组(int[]arr){
Set currentnums=newhashset();
对于(int i=0;i
您可以先固定起始位置,然后继续交换。这是最容易理解的方法之一

public class PermutationListRecursion {

    private Set<List<Integer>> permList = new HashSet<>();

    public static void main(String[] args) {
        PermutationListRecursion pt = new PermutationListRecursion();
        Integer[] nums = { 1, 2, 3 };
        pt.permute(nums);
        System.out.println(pt.permList);
    }

    public void permute(Integer[] nums) {
        permutation(0, nums.length - 1, nums);
    }

    public void permutation(int start, int end, Integer[] nums) {
        if (start == end) {
            permList.add(new ArrayList<Integer>(Arrays.asList(nums)));
        }
        for (int i = start; i <= end; i++) {
            permList.add(swap(nums, start, i));
            permutation(start + 1, end, nums);
            permList.add(swap(nums, start, i));
        }
    }

    private List<Integer> swap(Integer[] arr, int a, int b) {
        if (a == b) {
            return new ArrayList<>(Arrays.asList(arr));
        }
        Integer temp = arr[b];
        arr[b] = arr[a];
        arr[a] = temp;
        return new ArrayList<>(Arrays.asList(arr));
    }
}
公共类置换列表递归{
私有集permList=新HashSet();
公共静态void main(字符串[]args){
PermutationListRecursion pt=新的PermutationListRecursion();
整数[]nums={1,2,3};
pt.permute(nums);
系统输出打印LN(零件列表);
}
公共void排列(整数[]nums){
置换(0,nums.length-1,nums);
}
公共无效置换(整数开始、整数结束、整数[]nums){
如果(开始==结束){
添加(新的ArrayList(Arrays.asList(nums));
}

对于(int i=start;i我研究了这个线程,分析了正确的解决方案。不幸的是,我需要这个递归来处理大量输入,这将导致创建许多我不需要存储的对象,我想对每个排列应用一个方法,只保留满足我的算法的那些,所以我提出了这个解决方案。希望它能帮助别人

public static <E> void iteratePermutations(List<E> original, Consumer<List<E>> consumer) {
    Objects.requireNonNull(original);
    consumer.accept(original);
    iteratePermutationsRecursively(original, 0, consumer);
}

public static <E> void iteratePermutationsRecursively(List<E> original, int start, Consumer<List<E>> consumer) {
    Objects.requireNonNull(original);
    for (int i = start; i < original.size() - 1; i++) {
        for (int j = i + 1; j < original.size(); j++) {
            List<E> temp = new ArrayList<>(original);
            E tempVal = temp.get(i);
            temp.set(i, temp.get(j));
            temp.set(j, tempVal);
            consumer.accept(temp);
            iteratePermutationsRecursively(temp, i + 1, consumer);
        }
    }
}
公共静态无效迭代项(列出原始项、使用者){
对象。requirennull(原件);
消费者。接受(原件);
逐次迭代术语置换(原始,0,使用者);
}
公共静态void iteratePermutationsRecursive(列出原始、整数开始、使用者){
对象。requirennull(原件);
对于(int i=start;i
我可以被称为:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<List<Integer>> result = new ArrayList<>();
iteratePermutations(list, result::add);
List List=Arr
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<List<Integer>> result = new ArrayList<>();
iteratePermutations(list, result::add);
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
iteratePermutations(list, System.out::println);