2021-06-22

数据结构与算法分析-递归字符串全排列算法

题目如下:
编写带有下列声明的例程:

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[]的位数不断推进执行递归,即可得到预期的递归结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值