数据结构与算法分析-递归字符串全排列算法
题目如下:
编写带有下列声明的例程:
public void permute(String str);
private void permute(char[] str, int low, int high);
第一个例程是驱动程序,其调用第二个例程并显示String str中字符的所有排列。如"abc"的所有排列为"abc"、“acb”、“bac”、“bca”、“cab”、"cba"六种。
第二个例程需使用递归。
解题思路
递归的四条基本法则:
①基准情形:必须要有某些基准情形,在不需递归时就可得到解;
②不断推进:需要递归的情形中,每一次递归调用必须使状况朝向一种基准情形推进;
③设计法则:所有的递归调用都可运行;
④合成效益法则:求解一个问题的同一实例时,不要在递归调用做重复性的工作。
首先创建类:
public class myPermute {
static myPermute MyPermute = new myPermute();
public void permute(String str){
...
}
private void permute(char[] str, int low, int high){
...
}
}
然后设计驱动程序:
public void permute(String str)
{
char[] str_char = str.toCharArray();
// 调用递归方法
MyPermute.permute(str_char,0,str_char.length);
}
由于该递归方法涉及到字符串的交换,故需先设计出字符串交换的方法:
// 用于交换char[]中的两个元素
// 由于char[]为地址,故交换后不需返回char[]
private void swapElement(char[] str, int swap_a, int swap_b)
{
if ((swap_a >= 0) && (swap_b >= 0) && (swap_a != swap_b))
{
char swap = str[swap_a];
str[swap_a] = str[swap_b];
str[swap_b] = swap;
}
}
开始设计递归方法:
private void permute( char[] str, int low, int high)
{
if(low == high){
System.out.println(str);
}
else if(low > high){
System.out.println("VALUE ERROR");
}
else{
for(int i=low;i<high;i++)
{
//交换char中元素
MyPermute.swapElement(str,i,low);
//递归
MyPermute.permute(str,low+1,str.length);
//递归完毕后将交换的元素恢复
MyPermute.swapElement(str,i,low);
}
}
}
调用permute方法:
public static void main(String []args){
MyPermute.permute("123");
}
permute方法执行结果如下:
总结
在处理递归问题时,需对第一次递归的过程及递归的结果进行严格设计,而递归中间的过程不应过多考虑。
只需保障每一次递归都会将递归调用往基准情形推进即可。
以此题为例,将char[]的位数不断推进执行递归,即可得到预期的递归结果。