A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 莞漂族 中级黑马   /  2014-6-9 22:23  /  2116 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

/*5、 编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
原始字符串是"abc",打印得到下列所有组合情况:
"a" "b" "c"
"ab" "bc" "ca" "ba" "cb" "ac"
"abc" "acb" "bac" "bca" "cab" "cba"
*/

package com.itheima;

public class Test5
{
    public static String str = "abc";

    public static void main(String[] args)
    {
       show(0, new String());

    }

    public static void show(int current_recur, String temp)
    {
        if (current_recur < str.length())
        {
            for (int i = 0; i < str.length(); i++)
            {
                     
                if (!(temp.contains(str.substring(i, i + 1))))
                {
                    show(current_recur + 1, new String(temp + str.substring(i, i + 1)));

                    System.out.println(temp + str.substring(i, i + 1));

                }
            }   
        }
    }
}
if (current_recur < str.length()) 为什么要在满足current_recur < str.length()的条件下递归?

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

11 个回复

倒序浏览
何为递归,递归就是先"递"后"归",当current_recur + 1大于字符串的长度时str.length()时,你还有必要再"递"吗!
回复 使用道具 举报
为什么当current_recur + 1大于字符串的长度时str.length()时,没必要再"递"了?还有这个递归的过程看起来很复杂,我画图画不来,能不能说的详细些?我真的不懂,谢谢!
回复 使用道具 举报
我这个题目 是先把a b c的所有组合做出来  然后对每个组合全排列<这里递归>  代码比你的这个多的多  感觉你这个代码好屌啊 这么一点就实现了  不过我的那个可以a b c 中取任意的组合的全排列 比较灵活  
回复 使用道具 举报
2-----2-----ab--c
1-----1-----a--b
2-----1-----ac--b
1-----2-----a--c
0-----0-------a
2-----2-----ba--c
1-----0-----b--a
2-----0-----bc--a
1-----2-----b--c
0-----1-------b
外面那层if判断是提取str这个字符串的每一个字母。意思就是说,假设str为“abc",那么保证,第一大部分出现a开头的所有组合。即为:a,ab,ac,aba,acb。第二大部分出现的是b开头的所有组合,即为:b,ba,bc,bac,bca。依次类推,第三大部分为c开头的。
分析完大部分就看大部分中的内容是怎么输出的了。从上面打印出来的结果分析出来。如果temp中不包含str这个字符串的n位置的字符,那就打印出temp和n位置的值。并将n位置的字符加到temp中,并且从current_recur + 1开始递归。
分析a,ab,ac,aba,acb怎么得来的就知道,
比如第一次外循环0时,内循环为0时,可打印出 a ,同时show(1,a).这个show(1,a),temp值为a了,这时又可以组合在循环时可打印出ab,ac。在temp值为ab,时,又可以打印出abc来。在temp值为ac时,又可以打印出acb来。
反正就是在打印出来的每一个组合的基础上加上没有出现过的字母。
说得有点凌乱。。。了
回复 使用道具 举报
附上我的分析的代码,只改动了一下下输出。容易看效果。
  1. package com.study.three;

  2. public class Test6
  3. {
  4.     public static String str = "abc";

  5.     public static void main(String[] args)
  6.     {
  7.        show(0, new String());

  8.     }

  9.     public static void show(int current_recur, String temp)
  10.     {
  11.         if (current_recur <str.length())
  12.         {
  13.             for (int i = 0; i < str.length(); i++)
  14.             {
  15.                      
  16.                 if (!(temp.contains(str.substring(i, i + 1))))
  17.                 {
  18.                     show(current_recur + 1, new String(temp + str.substring(i, i + 1)));

  19.                     System.out.println(current_recur +"-----"+i+"-----"+temp+"--" + str.substring(i, i + 1));
  20.                   //  System.out.println(temp+str.substring(i, i + 1));

  21.                 }
  22.             }
  23.             
  24.         }
  25.     }
  26. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
观决 中级黑马 2014-6-10 12:17:39
7#
本帖最后由 观决 于 2014-6-10 12:22 编辑

我刚才分析了一下     就拿a b  c为例子吧
刚才是 进去第一个show(0,new String())----->current_recur 判断次数吧 最多递归str.length()次

过程大概这样
1:  temp 是空的 ----->!(temp.contains(str.substring(i, i + 1)))成立 ----->show(current_recur + 1, new String(temp + str.substring(i, i + 1))); current_recur +1=1


2:  temp = a      ------>!(temp.contains(str.substring(i, i + 1)))不成立  ---->i++一次  a不包括b -----这时候ab作为temp放进去  current_recur +1=2
3:     temp= ab   --------> 又从a开始遍历  发现a b  都有 c  没得   这次abc都放入 这时候 current_recur =3不满足条件 接着后面的运行 就第一次输出了abc


4:  然后这次的输出了 说明递归进来这次的完了 跳到上次递归开始的地方  这时候 temp=ab 同样输出 ab    这时候 有跳会上一级  temp=a  这时候因为这次的a值添加了b就满足条件去递归了  所以再次回来的时候 就是a里面包括c 吗这个条件  发现不包括 条件成立  以ac开始递归和上面的ab一样  同样输出acb  ac


5再次回来的时候a开头的已经完了   输出a


后面就是  b开头和a 一样   
我画了个图  我也只能呢过理解到这里了   


顺便说我的方法 我也是问网上看了有人用全排列    有人用组合    我把他们合起来了     自己修改了一下
  1. package com.libo.qusetion01;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;

  7. public class MyCombinationDemo {
  8.            /*  
  9.      * 设有n个元素,组合数量有2的n次方种。
  10.   * 对 0 到 2的n次方-1 中的每个数,考察其二进制位形式,位数为1代表相应元素加入到组合,0则不加入该元素至组合。
  11.   *
  12.       *     取组合方法  a2^0    b2^1     c2^2
  13.       *      这样 1 只有a
  14.       *                 2        b
  15.       *                 3        ab
  16.       *                 4        c
  17.       *                 5        ac
  18.       *         .......一次下去  所有的都出来了
  19.   *     参数: list ---- 原始数组
  20.   *     返回:  包含所有组合数组的数组
  21.   */
  22.         public static void main(String [] args){
  23.                 String [] strs=new String[]{"a","b","c"};
  24.                 //集合里面放集合 每个集合就是一个组合
  25.                 List<List<String>> result=new ArrayList<List<String>>();
  26.                 //获取所有的组合   用位移的方法
  27.                 getAllGroup(result,strs);
  28.                 System.out.println(Arrays.toString(strs)+"----组合情况如下------");
  29.            System.out.println(result);
  30.            System.out.println("------------全排列  ---------------");
  31.                 //根据获取的组合size>2的全排序
  32.            getAllSort(result);
  33.         }
  34.         private static void getAllSort(List<List<String>> result) {
  35.                 //如果是全排序的肯定有很多  都存入一个新的集合
  36.                 List<String> resultAll=new ArrayList<String>();
  37.                 for(List<String> list : result){
  38.                         if(list.size()>1){
  39.                                 //就将其全排序
  40.                                 int start=0;
  41.                                 int last=list.size()-1;
  42.                                 char [] buf=new char[list.size()];
  43.                                 for(int i=0;i<list.size();i++){
  44.                                         buf[i]=list.get(i).charAt(0);  //每个一个
  45.                                 }
  46.                                 List<String> listAll=new ArrayList<String>();
  47.                         completeSort(buf,start,last,listAll);       
  48.                         resultAll.addAll(listAll);   //加到里面
  49.                         }
  50.                         else{
  51.                         resultAll.addAll(list);
  52.                         }
  53.                 }
  54.                 //size大小排序
  55.                 Collections.sort(resultAll, new MyCompBySize());
  56.                 int size=1;
  57.                 for(int i=0;i<resultAll.size();i++){               
  58.                         if(resultAll.get(i).length()!=size){
  59.                                 System.out.println();
  60.                                 size++;
  61.                         }
  62.                         System.out.print(resultAll.get(i)+"  ");
  63.                 }       
  64.         }
  65.         //获取全排列
  66.         private static void completeSort(char[] buf, int start, int last, List<String> listAll) {
  67.                 //最后一了 直接可以输出了
  68.                  if(start==last){//当只要求对数组中一个字母进行全排列时,只要就按该数组输出即可  
  69.                              StringBuffer sb=new StringBuffer();
  70.                          for(int i=0;i<=last;i++){  
  71.                              sb.append(buf[i]);
  72.                          }  
  73.                          listAll.add(sb.toString());   
  74.                      }  
  75.                      else{//多个字母全排列      当原来第一个抽出来  排好之后  就拿到后一个与第一个换位子 这时重新上一步的全排序
  76.                                              //全排序之后 要不位子换回来  不用管中间的过程 只管开始的时候 然后是递归
  77.                          for(int i=start;i<=last;i++){  
  78.                              swap(buf,i,start);    //每次都拿和第一个位置交换  后面的就不用换  后面的用递归 自己会全排序的
  79.                              completeSort(buf,start+1,last, listAll);//后续元素递归全排列  
  80.                              swap(buf,i,start);
  81.                          }  
  82.                      }  
  83.         }
  84.         private static void swap(char[] buf, int i, int start) {
  85.                 char temp=buf[i];
  86.                 buf[i]=buf[start];
  87.                 buf[start]=temp;       
  88.         }
  89.         //获得所有的组合
  90.         private static void getAllGroup(List<List<String>> result, String[] strs) {
  91.                 //最大就这么大   1+2+4=7  \最大局势abc的情况
  92.                 int n=(int)Math.pow(2, strs.length);
  93.                 for(int i=1; i<n; i++){
  94.                         //用来存入 1的情况
  95.                         List<String> list=new ArrayList<String>();
  96.                         for(int j=0;j<strs.length; j++){
  97.                                 if(((i>>>j)&1)==1){
  98.                                         list.add(strs[j]);
  99.                                 }
  100.                         }
  101.                         result.add(list);   //组合加入最后的
  102.                 }       
  103.         }       
  104. }
  105. //自定义比较器
  106. class MyCompBySize implements Comparator<String>{

  107.         @Override
  108.         public int compare(String s1, String s2) {

  109.                 return s1.length()-s2.length();
  110.         }
  111.        
  112. }
复制代码
结果 为了


评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
很感谢你的耐心解答,但是我还有些疑问:show(0,' ');s.o.p('a')---->show(1,'a');s.o.p('ab')---->show(2,'ab');s.o.p('abc')---->show(3,'abc') ,  show(3,'abc')执行不到,因为current_recur为3不满足条件,之后就是打印'abc',再就是show(2,'ab')执行完了,打印'ab',然后为什么不打印'a',而是打印'acb'/'ac'/'a' ,最后才打印'a'?难道打印完'ab'后show(1,'a');还没执行完吗?还有就是从show(1,'a')到show(3,'ab')这过程中for循环里的i值应该是变为2了吧?可是退回到show(1,'a')时i的值是2还是多少?
回复 使用道具 举报
就看看 学习下
回复 使用道具 举报
莞漂族 发表于 2014-6-10 12:58
很感谢你的耐心解答,但是我还有些疑问:show(0,' ');s.o.p('a')---->show(1,'a');s.o.p('ab')---->show(2, ...

a进去开始选  选到b开始递归 这是时候 a 是一个人进入if里面的   他是判断b是否在a中   发现不在a一个人进去 递归的时候 传ab   之后打印的也是temp+选中的(这时候是ab)   这时候出了if选择开始c  然后进去c的递归

这才三个字符 你可以自己一步一步的把过程记下来 这样容易理解
回复 使用道具 举报
观决 发表于 2014-6-10 12:17
我刚才分析了一下     就拿a b  c为例子吧
刚才是 进去第一个show(0,new String())----->current_recur 判 ...

谢谢你的耐心回答,向你学习!
回复 使用道具 举报
莞漂族 发表于 2014-6-10 21:59
谢谢你的耐心回答,向你学习!

我基础测试 没遇到这题   我同学遇到了 我就做研究了一下  开始我也不会....{:2_33:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马