黑马程序员技术交流社区
标题:
编程列出一个字符串的全字符组合情况,集合解法
[打印本页]
作者:
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
抄了论坛里前辈的总结,给回复了一下。
突然想起,其实这个问题可以用集合来做。代码会简单一点。
做了半宿,结果出来了,果然我还是比较笨的。
以下代码
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;
}
}
复制代码
有什么需要改进的地方希望大家指正。
作者:
coolmiao13
时间:
2015-2-22 15:09
自己占一个楼。
作者:
小泽
时间:
2015-2-22 21:31
先占个地方 有时间自己看看
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2