黑马程序员技术交流社区

标题: 请高手分析一下这段代码的思路 [打印本页]

作者: 湛添友    时间: 2014-5-6 08:25
标题: 请高手分析一下这段代码的思路

//打印一个字符串及任意子串的任意排序
public class test
{
        public static void main(String[] args)
        {
                showPermString("abcd");
        }
        
        
        
        public static void showPermString(String str)
        {
                for(int i=1; i<=str.length(); i++)
                {
                        List<String> list = new ArrayList<String>();
                        perm(list, str.toCharArray(), 0, i);
                        System.out.println(list);
                }
        }

        
        
        
        public static void perm(List<String> list,char[] chs,int k,int len)
        {
                if(k == chs.length)
                {
                        String string = String.valueOf(chs, 0, len);
                        if(!list.contains(string))
                                list.add(string);
                }
                else
                {
                        for(int i=k; i<chs.length; i++)
                        {
                                swap(chs, i, k);
                                perm(list,chs, k+1,len);
                                swap(chs, i, k);
                        }
                }
               
        }
        
        public static void swap(char[] chs,int i,int j)
        {
                char tem = chs[i];
                chs[i] = chs[j];
                chs[j] = tem;
        }

}
作者: 神马    时间: 2014-5-6 10:11
我也是看了很久才明白,没有注释害死人啊。。。编程时是正的理解容易,看程序就要逆推了额。
首先这个程序是用递归实现字符串及其子串的全排列。其实只要理解了perm方法其他的就差不多了。perm使用递归实现一个字符串的全排列。然后showPermString方法每次循环截取一定的长度,就成了它相应子串的全排列。也就是说它求子串全排列的时候,也是把整串的全排列求出来,截取从0到len的一段,因为整串的全排列肯定包含了其所有子串的全排列。但是这样效率很低。正好我的基础测试就是这个,我把我的代码给你看看。当字符串在“abcdefghi”这样长度的时候,两个程序的速度差距就很明显了。
  1. package com.itheima;
  2. /**
  3. * 第五题:编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
  4. * 原始字符串是"abc",打印得到下列所有组合情况:
  5. * "a" "b" "c"
  6. * "ab" "bc" "ca" "ba" "cb" "ac"
  7. * "abc" "acb" "bac" "bca" "cab" "cba"
  8. * @author JunZhu
  9. */
  10. import java.util.ArrayList;
  11. public class Test5 {
  12.         public static void main(String[] args){
  13.                  //创建一个字符串,并调用allGroups方法输出其全字符组合
  14.                 String s="abc";
  15.                 System.out.println(s+"的全字符排列组合为:");
  16.                 allGroups(s);
  17.         }
  18.         //创建一个方法,用于输出指定字符串的全字符组合
  19.         public static void allGroups(String s){
  20.                 //把字符串转换为字符数组
  21.                 char[] c=s.toCharArray();
  22.                 int l=s.length();
  23.                 String[] sc=new String[l];
  24.                 //创建一个ArrayList字符串容器al
  25.                 ArrayList<String> al=new ArrayList<String>();
  26.                 //给集合al和字符串数组sc赋初始值
  27.                 for(int a=0;a<l;a++){
  28.                         sc[a]=String.valueOf(c[a]);
  29.                         al.add(sc[a]);
  30.                 }
  31.                 //while循环,判断条件为组合的长度是否到了最大值
  32.                 while(al.get(al.size()-1).length()<l){
  33.                         //al2用于临时存放当前长度的字符串的所有可能组合
  34.                         ArrayList<String> al2=new ArrayList<String>();
  35.                         //for循环表示,当首字符为sc[i]时,当前长度字符串的所有可能组合
  36.                         for(int i=0;i<l;i++){
  37.                                 //这个增强for循环用来取al中的字符串,当满足不重复的条件时,就与首字符sc[i]进行组合
  38.                                 for(String s1:al){
  39.                                         if(s1.contains(sc[i])||al.get(al.size()-1).length()!=s1.length()) continue;
  40.                                         al2.add(sc[i]+s1);
  41.                                 }
  42.                         }
  43.                         //将当前长度字符串的所有组合存入al中,之后进入下一个长度的排列组合
  44.                         for(String s2 : al2) al.add(s2);
  45.                 }
  46.                 //输出al中的所有组合,由于ArrayList是有序的,因此可以按照组合字符串中字符个数按行输出
  47.                 int b=1;
  48.                 for(String s3:al){
  49.                         if(s3.length()!=b) System.out.println();
  50.                         System.out.print(s3+"\t");
  51.                         b=s3.length();
  52.                 }
  53.         }
  54. }
复制代码

作者: jieyu90    时间: 2014-5-6 10:35
Mark,等会回来看看
作者: renshu16    时间: 2014-5-6 14:04
学习了,很详细




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2