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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

wokua

初级黑马

  • 黑马币:39

  • 帖子:24

  • 精华:0

© wokua 初级黑马   /  2015-10-30 16:12  /  2106 人查看  /  15 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

输出任意字符串的全组合情况
如:
输入"abc"
输出结果为:
"a" "b" "c"
"ab" "ac" "bc" "ba" "ca" "cb"
"abc" "acb" "bca" "bac" "cab" "cba"

15 个回复

倒序浏览
  1. public class Test2 {
  2.         public static void main(String[] args) throws Throwable {
  3.                 Scanner scan = new Scanner(System.in);
  4.                 String str = scan.nextLine();
  5.                 String[] ss = str.split("");
  6.                 for (int i = 1; i <= ss.length; i++) {

  7.                         List<List<String>> result = parade(Arrays.asList(ss), i);
  8.                         for (List<String> l : result) {
  9.                                 for (String string : l) {
  10.                                         System.out.print(string);
  11.                                 }
  12.                                 System.out.print(" ");
  13.                         }
  14.                         System.out.println();
  15.                         // System.out.printf("total:%s\n", result.size());
  16.                 }
  17.         }

  18.         public static List<List<String>> parade(List<String> data, int num) {
  19.                 List<List<String>> result = new ArrayList<List<String>>();
  20.                 if (num == 1) { // 只排一个元素的时候(递归结束条件)
  21.                         for (String s : data) {
  22.                                 List<String> l = new ArrayList<String>();
  23.                                 l.add(s);
  24.                                 result.add(l); // 每个元素分别保存到结果集
  25.                         }
  26.                         return result; // 并返回结果集
  27.                 }

  28.                 for (int i = 0; i < data.size(); i++) { // num>1,即排多个元素的时候,循环
  29.                         List<String> list = new ArrayList<String>(data);
  30.                         list.remove(i); // 去掉当前循环的元素作为下次递归的参数,即剩余的元素做递归
  31.                         List<List<String>> sub = parade(list, num - 1); // 递归调用
  32.                         for (List<String> l : sub) { // 然后循环递归得到的结果
  33.                                 l.add(0, data.get(i)); // 把当前元素排在每个结果的前面
  34.                                 result.add(l); // 并保存到结果集
  35.                         }
  36.                 }

  37.                 return result; // 最后返回结果集
  38.         }
  39. }
复制代码


参考网上并修改的,不懂的地方一起探讨哈

评分

参与人数 1黑马币 +5 收起 理由
sabrina妖儿 + 5 赞一个!

查看全部评分

回复 使用道具 举报
xingjiyuan26 发表于 2015-10-30 18:47
参考网上并修改的,不懂的地方一起探讨哈

递归里的list可以考虑定义成LinkedList,因为删除、添加操作比较多,可以提高效率
回复 使用道具 举报
回复 使用道具 举报
还没学到递归,好想看不懂啊
回复 使用道具 举报
我也是刚刚做过这道题,看看我的代码呗,但是一定要看懂啊,如果发现我的代码有什么问题一定指出来
  1. public class Tes{
  2.         public static void main(String[] args) {
  3.                 //创建Scanner对象,获取控制台输入
  4.                 Scanner sc = new Scanner(System.in);
  5.                 System.out.println("请输入一个原始字符串");
  6.                 //等待输入
  7.                 String next = sc.next();
  8.                 //将获取的字符串转换为字符数组,便于操作
  9.                 char[] charArray = next.toCharArray();
  10.                 System.out.println("原始字符串中所有字符组合如下:");
  11.                 //打印一个字符的所有组合
  12.                 for (int i = 0; i < charArray.length; i++) {
  13.                         System.out.print("\""+charArray[i]+"\"  ");
  14.                 }
  15.                 System.out.println();
  16.                 //打印两个字符的所有组合
  17.                 for (int i = 0; i < charArray.length; i++) {       
  18.                         for (int j = 0; j < charArray.length; j++) {
  19.                                 if(j!=i){
  20.                                         System.out.print("\""+charArray[i]+charArray[j]+"\"  ");
  21.                                 }
  22.                                
  23.                         }
  24.                 }
  25.                 System.out.println();
  26.                 //打印三个字符的所有组合
  27.                 for (int i = 0; i < charArray.length; i++) {       
  28.                         for (int j = 0; j < charArray.length; j++) {
  29.                                 for (int k = 0; k < charArray.length; k++) {
  30.                                         if (i!=j&&i!=k&&j!=k) {
  31.                                                 if(j!=i){
  32.                                                         System.out.print("\""+charArray[i]+charArray[j]+charArray[k]+"\"  ");
  33.                                                 }
  34.                                         }
  35.                                 }                       
  36.                         }
  37.                 }
  38.         }
  39. }
复制代码




点评

你的代码有问题 如果输入的是abcd 你的代码就不管用了  发表于 2015-11-1 15:20
刚刚看了一下,楼主下次能把分析思路写出来就更好了  发表于 2015-10-31 21:18
回复 使用道具 举报

  1. import java.util.ArrayList;
  2. import java.util.Comparator;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import java.util.TreeSet;


  6. /**
  7. * 第八题:编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,
  8. *  例如:原始字符串是"abc",
  9. *   打印得到下列所有组合情况:
  10. *   "a" "b" "c"
  11. * "ab" "bc" "ca" "ba" "cb" "ac"
  12. * "abc" "acb" "bac" "bca" "cab" "cba"
  13. *
  14. * 分析:
  15. *         通过将单个字符组合得到两个字符连在一起的双字符字符串,一次类推,直到得到所有字符组合。
  16. *         将得到字符组合重新放入到TreeSet中,为该TreeSet添加Comparator匿名类,满足题目显示顺序要求。
  17. * @author Administrator
  18. *
  19. */
  20. public class Test08 {

  21.         public static void main(String[] args) {
  22.                 String str = "abcd";
  23.                 printList(randomChars(str));
  24.                
  25.         }
  26.         /**
  27.          *
  28.          * @param str        要查找字符组合的字符串
  29.          * @return 返回字符串中字符组合。
  30.          */
  31.         public static List<String> randomChars(String str){
  32.                 //初始化要存储新字符组合的列表对象。
  33.                 List<String> list = new ArrayList<>();
  34.                 //将传入的字符串参数分解为单个字符
  35.                 String[] arr = str.split("");
  36.                
  37.                 //将但字符加入到列表集合中
  38.                 for(String element : arr){
  39.                         list.add(element);
  40.                 }
  41.                
  42.                 //使用嵌套循环组合各种字符并且将新字符组合放入列表中。
  43.                 for(int i = 0; i < list.size(); i++){                //外部循环,用于获取列表中已有字符串
  44.                         for(int j = 0; j < arr.length; j++){        //内部循环,用于为原有的字符串加上字符。
  45.                                
  46.                                 //判断字符是否存在于某个字符串,不存在就加上。
  47.                                 if(!list.get(i).contains(arr[j])){
  48.                                         list.add(list.get(i) + arr[j]);
  49.                                 }
  50.                         }
  51.                 }
  52.                
  53.                 //返回获得的字符列表。
  54.                 return list;
  55.         }
  56.        
  57.         public static void printList(List<String> list){
  58.                 //获得用匿名Comparator对象作为参数的TreeSet
  59.                 TreeSet<String> tss = new TreeSet<>(new Comparator<String>() {

  60.                         @Override
  61.                         public int compare(String str1, String str2) {
  62.                                 int len1 = str1.length();
  63.                         int len2 = str2.length();
  64.                         //如果字符长度相等,就按照字典顺序排列字符串
  65.                         if(len1 == len2){
  66.                                 return str1.compareTo(str2);
  67.                         }
  68.                         
  69.                         //如果字符串长度不相等,就将短的字符串放到前面。
  70.                         return len1 - len2;

  71.                         }
  72.                        
  73.                 });
  74.                
  75.                 //将参数中元素加入到TreeSet对象
  76.                 tss.addAll(list);
  77.                
  78.                 //判断字符串长度
  79.                 int length = 1;
  80.                
  81.                 //使用foreach循环遍历数组
  82.                 for(String str : tss){
  83.                         //如果字符串长度增加,就进行换行。
  84.                         if(str.length() > length){
  85.                                 System.out.println();
  86.                                 length++;
  87.                         }
  88.                         System.out.print("\"" + str + "\" ");
  89.                 }
  90.         }
  91.        
  92. }
复制代码


Perfect
回复 使用道具 举报
又来了
  1. /*
  2. 需求:输出任意字符串的全组合情况如:
  3. 输入"abc"
  4. 输出结果为:
  5. "a" "b" "c"
  6. "ab" "ac" "bc" "ba" "ca" "cb"
  7. "abc" "acb" "bca" "bac" "cab" "cba"
  8. */
  9. import java.util.Scanner;
  10. import java.util.ArrayList;
  11. import java.util.ListIterator;
  12. class Demo
  13. {
  14.         public static void main(String[] args)
  15.         {
  16.                 System.out.println("输入你要排列的字符串:");
  17.                 //创建Scnnner扫描器对象 获取控制台输入
  18.                 Scanner sc = new Scanner(System.in);
  19.                 //等待输入
  20.                 String str = sc.nextLine();
  21.                 //把字符串转换成字符数组
  22.                 char[] chr = str.toCharArray();  
  23.                 int len = chr.length;
  24.                 //创建一个Arraylist对像 用于存储各种组合情况
  25.                 ArrayList<String> al = new ArrayList<String>();
  26.                
  27.                 //返回一个ArrayList集合引用 该集合中存储了字符串各种组合情况 用newal来接受这个引用
  28.                 ArrayList<String> newal = getGroups(al,chr,len);
  29.                
  30.            //增强for遍历集合 和 打印所有情况
  31.                 for(String s : newal)   
  32.                 {
  33.                         System.out.println(s);
  34.                 }
  35.                 System.out.println("一共有:"+newal.size()+"个组合");
  36.         }
  37.         /*
  38.         这个函数的作用是将所有的组合情况存入ArrayList集合中
  39.         其中用到了递归 判断是否结束条件是n==1
  40.         */
  41.         public static ArrayList<String> getGroups(ArrayList<String> al,char[] chr,int n)
  42.         {
  43.                 if(n==1)
  44.                 {
  45.                         for(int x=0; x<chr.length ;x++)
  46.                         {
  47.                                 al.add(chr[x]+"");
  48.                         }
  49.                 }
  50.                 else
  51.                 {
  52.                         al = getGroups(al,chr,n-1);
  53.                         for(int x=0; x<chr.length; x++)
  54.                         {
  55.                                 ListIterator<String> it = al.listIterator();
  56.                                 while(it.hasNext())
  57.                                 {
  58.                                         String s = it.next();
  59.                                         String newstr = chr[x]+""+s;
  60.                                         /*
  61.                                         这里的if是判断字符是否重复和字符串是否重复
  62.                                         提示:其实可以用TreeSet来代替ArrayList集合 那么newstr.length()==n 这句就可以不要了
  63.                                         因为TreeSet元素不可以重复
  64.                                        
  65.                                         我建议用TreeSet集合 同时可以自定义比较器 排列元素
  66.                                         我的这段代码可能导致输出无序 所以还是用TreeSet吧
  67.                                         楼主自己改吧 看到币还没送出 所以就写了 希望把币给我 缺技术分啊~~
  68.                                         */
  69.                                         if((!s.contains(chr[x]+""))&&(newstr.length()==n))
  70.                                                 it.add(newstr);
  71.                                 }
  72.                         }
  73.                 }
  74.                 return al;
  75.         }
  76. }
复制代码
回复 使用道具 举报
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Scanner;

  4. public class pai {
  5.     private static char[] is ;
  6.     private static int total;
  7.     private static int m;
  8.     public static void main(String[] args) {
  9.             Scanner sc = new Scanner(System.in);
  10.         List<Integer> iL = new ArrayList<Integer>();
  11.         System.out.println("请输入一串字符");
  12.         String next = sc.next();
  13.         is = next.toCharArray();
  14.         m=next.length();
  15.         for (int i = 1; i <= m; i++) {
  16.                  new pai().plzh("", iL,  i);
  17.                  System.out.println();
  18.                 }
  19.         System.out.println("total : " + total);
  20.     }
  21.     private void plzh(String s, List<Integer> iL, int m) {
  22.         if(m == 0) {
  23.             System.out.print(s+"\t");
  24.             total++;
  25.             return;
  26.         }
  27.         List<Integer> iL2;
  28.         for(int i = 0; i < is.length; i++) {
  29.             iL2 = new ArrayList<Integer>();
  30.             iL2.addAll(iL);
  31.             if(!iL.contains(i)) {
  32.                 String str = s + is[i];
  33.                 iL2.add(i);
  34.                 plzh(str, iL2, m-1);
  35.             }
  36.         }
  37.     }
  38. }
复制代码
网上找到的 稍作修改。
回复 使用道具 举报
黑马面试题么?
回复 使用道具 举报
xingjiyuan26 发表于 2015-10-30 18:47
参考网上并修改的,不懂的地方一起探讨哈

赞一个!!!
回复 使用道具 举报
方法很多,String里有个CharAt(index)方法,可遍历任意一个字符串即可
//new一个集合来存放
List list=new ArrayList();
//遍历
for(int i=0;i<str.length();i++){
     //添加到集合中
    list.add( str.CharAt(i)+"");
}
System out println(list);
回复 使用道具 举报
http://blog.csdn.net/qq_23077365/article/details/49582563
回复 使用道具 举报
我也遇到了这个面试题:给出我写的答案
  1. import java.util.*;
  2. /**
  3. * 第7题:编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
  4. * 原始字符串是"abc",打印得到下列所有组合情况:
  5. * 思路:通过对如下排列观察,发现字符串中,总是有重复的部分,只要把重复的部分取出,
  6. * 把剩下的连接,再重复以上操作即可
  7. *"a" "b" "c"
  8. *"ab" "bc" "ca" "ba" "cb" "ac"
  9. *"abc" "acb" "bac" "bca" "cab" "cba"
  10. * @author Administrator
  11. *
  12. */
  13. public class Test7 {
  14.         public static int count;//计数器--记录某一字符串任意不重复组合情况个数
  15.         public static void main(String[] args) {
  16.                 Scanner input=new Scanner(System.in);
  17.                 //开始
  18.                 while(true){
  19.                         count=0;
  20.                         System.out.print("请输入(输入over结束):");
  21.                         String str=input.next();//得到键盘录入字符串
  22.                         if(str.equals("over"))break;//循环截止
  23.                         getRange("",str);//调用方法求组合情况
  24.                         System.out.println("\n"+str+"有以上"+count+"种任意不重复组合情况");
  25.                 }
  26.         }
  27.         /**
  28.          * 发现:把字符串分成左右可改变和不可改变的部分,先循环得到每个字符的不同组成,再递归求解
  29.          * @param strLeft 组合的不可变部分
  30.          * @param strRight 组合可变部分
  31.          */
  32.         public static void getRange(String strLeft,String strRight){
  33.             for(int i=0;i<strRight.length();i++){//循环,得到每次右边的组合情况
  34.                         StringBuilder sb = new StringBuilder(strRight);//转换成StringBuilder
  35.                         String str = strLeft+strRight.substring(i, i+1);
  36.                         System.out.println(str);;//不可变部分+当前字符就等于当前的组合情况
  37.                         count++;
  38.                         getRange(str,sb.deleteCharAt(i).toString());
  39.                         //使用StringBuilder方法deleteCharAt删除当前当做可改变部分参数,再递归得到其他组合
  40.             }
  41.         }
  42. }
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马