递归的应用_字符所有的排列组合

来源:互联网 发布:大数据产生 编辑:程序博客网 时间:2024/05/17 08:26

 递归在数学上属于归纳法的范畴,在编写递归例程的时候要注意四条基本原则:

1.基准情形,必须总是要有基准情形,它无需归纳就能解除。

2.不断推进,对于那些需要递归求解的情形,每一次递归都必须使情况超一种基准情形推进。

3.设计法则,假设所有的递归都能运行。

4.合成效益法则,在求解一个问题的同一个实例时,不要在不同的递归调用中做重复的工作。

其实我们只要记住这4条法则,那么递归程序的设计就应该是简单明了了。下面我们以打印字符所有的排列组合为例,进行分析。

题目:假设有一个字符数组,如char[] str = new char[]{'a', 'b', 'c'};那么输入这个字符数组所有的排列组合:abc acb bac bca cab cba。字符数组任意。

 

这个例子的总体思路是:

     1. 按次序,把数组中的所有元素移动到下标为0的位置,剩余元素移动到下标1~str.length-1的位置。

     2.根据步骤1,保证下标为0元素不动,按次序,把1~str.length-1元素移动到下标1的位置,剩余元素移动到下标2~str.length-1的位置。

     3.根据步骤2,保证下标为0,1元素不动,按次序,把2~str.length-1元素移动到下标1的位置,剩余元素移动到下标3~str.length-1的位置。

    类推,一直到字符数组结束。

   那么总结一下,假设当前要移位的下标为low(因为从低位0开始),那么我们要做的事情是

  保证[0-low)的元素不动,按次序把把[low-str.length-1]元素移动到下标low的位置,剩余元素移动到下标(low-str.length-1]的位置。

根据递归的设计原则:

1.基准情形:当low==str.length-1时(移动到数组的结束),打印出字符数组str

public static void main(String[] args) {char[] str = new char[]{'a', 'b', 'c'};permute(str, 0);}/** * @Title: permute * @Description: 把[low-str.length-1]元素移动到下标low的位置 * 1.当结束时打印字符数组 * 2.没有结束,继续递归调用 * @param str,字符数组 * @param low,要移位的下标 * @throws */public static void permute(char[] str,int low) {if(low == str.length - 1) {System.out.println(new String(str));}else{char temp;//临时字符,用来交换元素。for(int i = low;i <= str.length - 1;i++) {//依次把下标为low与high进行交换,相当于移位操作。temp = str[low]; str[low] = str[i];str[i] = temp;//递归(不停的移位),一直到数组下标的最后。                permute(str.clone()//Java传引用,防止移位操作对后续程序的影响                , low + 1);}}}


 

2.不断推进:保证[0-low)的元素不动,按次序把把[low-str.length-1]元素移动到下标low的位置,剩余元素移动到下标(low-str.length-1]的位置。

3,4条原则没有用上。

说的可能不太明白,可以直接省略,看代码吧。

 

 

原创粉丝点击