本帖最后由 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
抄了论坛里前辈的总结,给回复了一下。
突然想起,其实这个问题可以用集合来做。代码会简单一点。
做了半宿,结果出来了,果然我还是比较笨的。
以下代码
- package ch01;
- import java.util.ArrayList;
- import java.util.Iterator;
- public class LieJu {
- public static void main(String[] args) {
- //调用方法,传入字符串
- zuHe.show("abca");
- }
- }
- class zuHe{
- public static void show(String str){
- ArrayList <String> al = new ArrayList<String>();
- //如果字符串长度比1大,那么做后面的事情
- if (str.length()>1){
- //将单个字符转换成单个的字符串存储进al容器里
- for(int i=0;i<str.length();i++){
- al.add(String.valueOf(str.charAt(i)));
- }
- //x为每行单个字符串的长度,第一行已经输出,所以从2开始,最长为原始字符串长度,循环输出每行组合
- for(int x=2;x<=str.length();x++){
- al =addChar(al,str);
- }
- //去除重复的元素
- al=singleElement(al);
- //按照格式打印容器中元素
- PrintArray(al);
- //比1小,直接打印字符串
- }else
- System.out.println(str);
- }
- public static ArrayList<String> addChar(ArrayList<String> al,String str){
- //创建一个临时容器,并把参数的元素存储到临时容器中
- ArrayList <String> a2 = new ArrayList<String>();
- a2.addAll(al);
- //外循环,遍历容器中得所有元素
- for(int y=0;y<al.size();y++){
- //内循环,遍历每个原始字符串的单个字符,将每个字符串把每个不同字符都单独添加一次
- for(int z=0;z<str.length();z++){
- //判断字符串是否包含该字符
- char str1 = str.charAt(z);
- if(al.get(y).indexOf(str1)>=0)
- continue;
- //不包含该字符,则添加该字符
- a2.add(al.get(y)+(str.charAt(z)));
- }
- }
- return a2;
- }
- //直接拿来毕老师的例子,添加了泛型。
- public static ArrayList<String> singleElement(ArrayList<String> al)
- {
- //定义一个临时容器。
- ArrayList<String> newAl = new ArrayList<String>();
- Iterator<String> it = al.iterator();
- while(it.hasNext())
- {
- String str = it.next();
- if(!newAl.contains(str))
- newAl.add(str);
- }
- return newAl;
- }
- public static void PrintArray(ArrayList<String> al){
- //遍历容器中元素,定义初始长度为1
- for (int i=0,len=1;i<al.size();i++){
- //如果长度没有变化,继续输出
- if (len==al.get(i).length()){
- System.out.print("\""+al.get(i)+"\"");
- }
- //如果长度变化,换行输出
- else{
- System.out.println();
- System.out.print("\""+al.get(i)+"\"");
- }
- //保存上一次长度
- len = al.get(i).length();
- }
- }
- }
复制代码
对了,下面是论坛前辈的方法,用的是数组地址是
http://bbs.itheima.com/thread-145369-1-1.html
我把代码压缩了下:
- class zuHe {
- //编写方法,接收字符串
- public static void show(String str){
- //将原始字符串转成原始字符数组
- char[] chs=str.toCharArray();
- //获得原始字符串数组,即每个字符串只有一个字符
- String[] strs=chsToStrs(chs);
- //按指定格式输出原始字符串数组,即单个字符的组合情况
- printString(strs);
- //x为每行单个字符串的长度,第一行已经输出,所以从2开始,最长为原始字符串长度,循环输出每行组合
- for(int x = 2;x<=str.length();x++){
- //调用方法,传入 原始字符数组 和 前一次的字符串数组,获得新的字符串数组
- strs=addChar(chs,strs);
- //按指定格式输出新的字符串数组
- printString(strs);
- }
- }
- //定义方法,接收 原始字符数组 和 前一次的字符串数组,并返回新字符串数组
- public static String[] addChar(char[] chs,String[] oldStrs){
- //因为新字符数组长度暂时无法确定,也为了转换方便,所以使用StringBuilder来接收每个新字符串
- StringBuilder sb=new StringBuilder();
- //定义新字符串数组
- String[] newStrs=null;
- //外循环,遍历每个字符串数组
- for(int x=0;x<oldStrs.length;x++){
- //内循环,遍历每个原始字符,将每个字符串把每个不同字符都单独添加一次
- for(int y=0;y<chs.length;y++){
- //判断字符串是否包含该字符,通过indexOf()的返回值>=0来确定已包含
- if(oldStrs[x].indexOf(chs[y])>=0)
- //已包含该字符,则不操作,继续下次循环
- continue;
- //不包含该字符,则添加该字符
- String s=oldStrs[x]+chs[y];
- //添加新字符串到StringBuilder对象并用','隔开
- sb.append(s).append(',');
- }
- }
- //删除StringBuilder对象最后的一个',',并转成字符串,再将字符串按','切割,获得新字符串数组
- newStrs=sb.deleteCharAt(sb.length()-1).toString().split(",");
- //返回新字符串数组
- return newStrs;
- }
- //将指定字符串数组按指定格式输出并换行
- public static void printString(String[] strs){
- for(String s:strs){
- System.out.print("\""+s+"\"");
- }
- System.out.println();
- }
- //将指定字符数组转成字符串数组,即每个字符串只有一个字符,并返回
- public static String[] chsToStrs(char[] chs){
- //字符串数组长度和字符数组长度一致
- String[] strs=new String[chs.length];
- for(int x=0;x<chs.length;x++)
- //将单个字符转成单个字符的字符串
- strs[x]=chs[x]+"";
- return strs;
- }
- }
复制代码 有什么需要改进的地方希望大家指正。
|