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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

package com.itheima;

/**
* 8、 编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
*
*
*
* 原始字符串是"abc",打印得到下列所有组合情况:

* "a" "b" "c"

* "ab" "bc" "ca" "ba" "cb" "ac"

* "abc" "acb" "bac" "bca" "cab" "cba"
* @author mars
*/
public class Test8
{
        public static void main(String[] args)
        {
                String str = "abc";//定义指定数组
               
                myCombinationAanRange(str);
               
            System.out.println("共有"+num+"个");//输出共有多个数。       
        }
       
       
        public static void myCombinationAanRange(String str)
        {
                char[] ch = new char[1024];
                int n = str.length();//元素个数。
               
            //求出位图全组合的结果个数:2^n
            int nbit = 1<<n; // “<<” 表示 左移:各二进位全部左移若干位,高位丢弃,低位补0。:即求出2^n=2Bit。
            
            int x = 0;//临时c数组下标变量
            
            for(int i=0; i<nbit; i++)//结果有nbit个。输出结果从数字小到大输出:即输出0,1,2,3,....2^n。
            {           
                for(int j=0; j<n ; j++)//每个数二进制最多可以左移n次,即遍历完所有可能的变化新二进制数值了
                {   
                        if ((i & (1 << j)) != 0)//& 表示与。两个位都为1时,结果才为1
                        {                           
                       ch[x++] = str.charAt(j);//放入c数组中。
                    }
                }
                allPerm(ch,0,x-1);//全排列
                x = 0;//数组下标归0
            }
        }
       
        private static int num = 0;//计全排列个数
        //全排列
        public static void allPerm(char[] arr , int start,int end)
        {
        //输出arr[start..end]的所有排列方式
        if(start == end)
        {   
                //输出一个排列方式
            for(int j=0; j<= end ;j++)
            {
                System.out.print(arr[j]);
            }
            System.out.println();
            num++;
        }

        for(int i = start; i <= end ; i++)
        {
            swap(arr, i, start);
            allPerm(arr, start+1, end);  //固定好当前一位,继续排列后面的
            swap(arr, i, start);
        }   
    }
        //交换
        private static void swap(char[] arr, int start, int i)
        {
                char tmp = arr[start];
                arr[start] = arr[i];
                arr[i] = tmp;
        }
}


4 个回复

倒序浏览
能继续解释下这个吗
回复 使用道具 举报
夏木南生 发表于 2015-9-23 22:27
能继续解释下这个吗

你是哪里不明白?
回复 使用道具 举报
  1. package com.itheima;

  2. import java.util.ArrayList;
  3. import java.util.Scanner;

  4. /**
  5. * 7、 编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
  6. * 原始字符串是"abc",打印得到下列所有组合情况:
  7. * "a" "b" "c"
  8. * "ab" "bc" "ca" "ba" "cb" "ac"
  9. * "abc" "acb" "bac" "bca" "cab" "cba"
  10. */
  11. public class Test7 {
  12.         public static void main(String[] args) {
  13.                 System.out.println("请输入一个字符串:");
  14.                 String str = new Scanner(System.in).nextLine();
  15.                 printGroups(str);// 打印字符串的所有组合
  16.         }
  17.         /**
  18.          * printGroups 该函数用于打印所有的字符串组合
  19.          * @param str 传入的原始字符串
  20.          */
  21.         public static void printGroups(String str) {
  22.                 char[] chs = str.toCharArray();//原始字符串转化为数组
  23.                 ArrayList<String> list = new ArrayList<String>();//存储所有的组合
  24.                 for (char ch : chs)
  25.                         list.add("" + ch);//向集合list添加所有的长度为1的字符串组合
  26.                 ArrayList<String> tempList = null;
  27.                
  28.                 //第1次循环,实现向集合list添加所有长度为2的组合,
  29.                 //第2次循环,实现向集合list添加所有长度为3的组合,....
  30.                 //第(n-1)次循环,实现向集合list添加所有长度为n的组合。
  31.                 for (int k = 0; k < chs.length; k++) {
  32.                         tempList = select(list, k + 1);// 过滤出长度为 (k+1)的字符串
  33.                         getTempGroup(chs, tempList, list);// 获取长度为(k+2)的字符串组合,并存入集合
  34.                 }
  35.                 // 遍历集合输出所有的组合
  36.                 for (String s : list)
  37.                         System.out.println(s);
  38.                 System.out.println("组合的总个数为: " + list.size());
  39.         }
  40.         /**
  41.          * getTempGroup 在第k次循环时,获取所有长度为(k+1)的组合,并添加到list集合
  42.          * @param chs 输入字符串对应的字符数组
  43.          * @param tempList 第k次循环时,存储的是长度为(k+1)的所有字符串组合
  44.          * @param list 存储所有的字符串组合
  45.          *
  46.          * 基本思路:获取n个不重复字符的所有排列组合:
  47.          *                 1  获取n个不重复的字符
  48.          *                 2 获取所有的长度为(n-1)的组合
  49.          *                 3 依次将单个字符与所有长度为(n-1)的字符串拼接,即可得到长度为n的所有组合
  50.          */
  51.         private static void getTempGroup(char[] chs, ArrayList<String> tempList,
  52.                         ArrayList<String> list) {
  53.                 int n = tempList.size();
  54.                 for (int i = 0; i < chs.length; i++) {
  55.                         for (int j = 0; j < n; j++) {
  56.                                 if (!tempList.get(j).contains("" + chs[i])) {// 字母没有重复
  57.                                         list.add("" + chs[i] + tempList.get(j));
  58.                                 }
  59.                         }
  60.                 }
  61.         }

  62.         /**
  63.          *
  64.          * @param list 需要被过滤的集合
  65.          * @param i        希望过滤出的字符串的长度
  66.          * @return as 返回存储所有长度为i的字符串的集合
  67.          */
  68.         private static ArrayList<String> select(ArrayList<String> list, int i) {
  69.                 ArrayList<String> as = new ArrayList<String>();
  70.                 for (String s : list) {
  71.                         if (s.length() == i)
  72.                                 as.add(s);
  73.                 }
  74.                 return as;
  75.         }
  76. }
  77. [code]请输入一个字符串:
  78. abc
  79. a
  80. b
  81. c
  82. ab
  83. ac
  84. ba
  85. bc
  86. ca
  87. cb
  88. abc
  89. acb
  90. bac
  91. bca
  92. cab
  93. cba
  94. 组合的总个数为: 15
复制代码
[/code]哈 我也抽到这一题了  分享一下我的代码
回复 使用道具 举报
递归部分的代码理解不来{:2_41:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马