黑马程序员技术交流社区

标题: 编程列出一个字符串的全字符组合情况,集合解法 [打印本页]

作者: coolmiao13    时间: 2015-2-22 01:30
标题: 编程列出一个字符串的全字符组合情况,集合解法
本帖最后由 coolmiao13 于 2015-2-22 01:33 编辑

原题如下:
编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如:
原始字符串是"abc",打印得到下列所有组合情况:
                "a" "b" "c"
                "ab" "bc" "ca" "ba" "cb" "ac"
                "abc" "acb" "bac" "bca" "cab" "cba"
这个题目是看了一个大哥的帖子,地址是
http://bbs.itheima.com/forum.php ... 9&page=1#pid1222518
抄了论坛里前辈的总结,给回复了一下。
突然想起,其实这个问题可以用集合来做。代码会简单一点。
做了半宿,结果出来了,果然我还是比较笨的。
以下代码
  1. package ch01;

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

  4. public class LieJu {
  5.     public static void main(String[] args) {
  6.         //调用方法,传入字符串
  7.         zuHe.show("abca");
  8.     }
  9. }
  10. class zuHe{
  11.     public static void show(String str){
  12.         ArrayList <String> al = new ArrayList<String>();
  13.         //如果字符串长度比1大,那么做后面的事情
  14.         if (str.length()>1){
  15.             //将单个字符转换成单个的字符串存储进al容器里
  16.             for(int i=0;i<str.length();i++){
  17.                 al.add(String.valueOf(str.charAt(i)));
  18.             }
  19.             //x为每行单个字符串的长度,第一行已经输出,所以从2开始,最长为原始字符串长度,循环输出每行组合
  20.             for(int x=2;x<=str.length();x++){
  21.                 al =addChar(al,str);
  22.             }
  23.             //去除重复的元素
  24.             al=singleElement(al);
  25.             //按照格式打印容器中元素
  26.             PrintArray(al);
  27.         //比1小,直接打印字符串
  28.         }else
  29.             System.out.println(str);
  30.     }
  31.     public static ArrayList<String> addChar(ArrayList<String> al,String str){
  32.         //创建一个临时容器,并把参数的元素存储到临时容器中
  33.         ArrayList <String> a2 = new ArrayList<String>();
  34.         a2.addAll(al);
  35.         //外循环,遍历容器中得所有元素
  36.         for(int y=0;y<al.size();y++){
  37.             //内循环,遍历每个原始字符串的单个字符,将每个字符串把每个不同字符都单独添加一次
  38.             for(int z=0;z<str.length();z++){   
  39.                 //判断字符串是否包含该字符
  40.                 char str1 = str.charAt(z);
  41.                 if(al.get(y).indexOf(str1)>=0)
  42.                     continue;
  43.                 //不包含该字符,则添加该字符
  44.                 a2.add(al.get(y)+(str.charAt(z)));   
  45.             }
  46.         }
  47.         return a2;
  48.     }
  49.     //直接拿来毕老师的例子,添加了泛型。
  50.     public static ArrayList<String> singleElement(ArrayList<String> al)
  51.     {
  52.        //定义一个临时容器。
  53.         ArrayList<String> newAl = new ArrayList<String>();
  54.         Iterator<String> it = al.iterator();
  55.         while(it.hasNext())
  56.         {
  57.             String str = it.next();
  58.             if(!newAl.contains(str))
  59.                 newAl.add(str);
  60.         }
  61.         return newAl;
  62.     }
  63.     public static void PrintArray(ArrayList<String> al){
  64.         //遍历容器中元素,定义初始长度为1
  65.         for (int i=0,len=1;i<al.size();i++){
  66.             //如果长度没有变化,继续输出
  67.             if (len==al.get(i).length()){
  68.                 System.out.print("\""+al.get(i)+"\"");
  69.             }
  70.             //如果长度变化,换行输出
  71.             else{
  72.                 System.out.println();
  73.                 System.out.print("\""+al.get(i)+"\"");
  74.             }
  75.             //保存上一次长度
  76.             len = al.get(i).length();
  77.         }
  78.     }
  79. }
复制代码

对了,下面是论坛前辈的方法,用的是数组地址是
http://bbs.itheima.com/thread-145369-1-1.html
我把代码压缩了下:
  1. class zuHe {
  2.     //编写方法,接收字符串
  3.     public static void show(String str){
  4.         //将原始字符串转成原始字符数组
  5.         char[] chs=str.toCharArray();
  6.         //获得原始字符串数组,即每个字符串只有一个字符
  7.         String[] strs=chsToStrs(chs);
  8.         //按指定格式输出原始字符串数组,即单个字符的组合情况
  9.         printString(strs);
  10.         //x为每行单个字符串的长度,第一行已经输出,所以从2开始,最长为原始字符串长度,循环输出每行组合
  11.         for(int x = 2;x<=str.length();x++){
  12.             //调用方法,传入 原始字符数组 和 前一次的字符串数组,获得新的字符串数组
  13.             strs=addChar(chs,strs);
  14.             //按指定格式输出新的字符串数组
  15.             printString(strs);
  16.         }
  17.     }
  18.     //定义方法,接收 原始字符数组 和 前一次的字符串数组,并返回新字符串数组
  19.     public static String[] addChar(char[] chs,String[] oldStrs){
  20.         //因为新字符数组长度暂时无法确定,也为了转换方便,所以使用StringBuilder来接收每个新字符串
  21.         StringBuilder sb=new StringBuilder();
  22.         //定义新字符串数组               
  23.         String[] newStrs=null;
  24.         //外循环,遍历每个字符串数组
  25.         for(int x=0;x<oldStrs.length;x++){
  26.             //内循环,遍历每个原始字符,将每个字符串把每个不同字符都单独添加一次
  27.             for(int y=0;y<chs.length;y++){
  28.                 //判断字符串是否包含该字符,通过indexOf()的返回值>=0来确定已包含
  29.                 if(oldStrs[x].indexOf(chs[y])>=0)
  30.                     //已包含该字符,则不操作,继续下次循环
  31.                     continue;
  32.                 //不包含该字符,则添加该字符
  33.                 String s=oldStrs[x]+chs[y];
  34.                 //添加新字符串到StringBuilder对象并用','隔开
  35.                 sb.append(s).append(',');
  36.             }
  37.         }
  38.         //删除StringBuilder对象最后的一个',',并转成字符串,再将字符串按','切割,获得新字符串数组
  39.         newStrs=sb.deleteCharAt(sb.length()-1).toString().split(",");
  40.         //返回新字符串数组
  41.         return newStrs;
  42.     }
  43.     //将指定字符串数组按指定格式输出并换行
  44.     public static void printString(String[] strs){
  45.         for(String s:strs){
  46.             System.out.print("\""+s+"\"");
  47.         }
  48.         System.out.println();
  49.     }
  50.     //将指定字符数组转成字符串数组,即每个字符串只有一个字符,并返回
  51.     public static String[] chsToStrs(char[] chs){
  52.         //字符串数组长度和字符数组长度一致
  53.         String[] strs=new String[chs.length];
  54.         for(int x=0;x<chs.length;x++)
  55.             //将单个字符转成单个字符的字符串
  56.             strs[x]=chs[x]+"";
  57.         return strs;
  58.     }
  59. }
复制代码
有什么需要改进的地方希望大家指正。




作者: coolmiao13    时间: 2015-2-22 15:09
自己占一个楼。
作者: 小泽    时间: 2015-2-22 21:31
先占个地方 有时间自己看看




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