黑马程序员_求任意字符串及其所有子串的全排列
来源:互联网 发布:无人机pos数据怎么确定 编辑:程序博客网 时间:2024/06/11 21:06
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
求任意字符串及其所有子串的全排列
这是我在黑马走流程的基础测试题中的一道,觉得很有意思。于是跟大家分享一下。
/** * 第五题:编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如: * 原始字符串是"abc",打印得到下列所有组合情况: * "a" "b" "c" * "ab" "bc" "ca" "ba" "cb" "ac" * "abc" "acb" "bac" "bca" "cab" "cba" * @author JunZhu */import java.util.ArrayList;public class Test5 {public static void main(String[] args){ //创建一个字符串,并调用allGroups方法输出其全字符组合String s="abc";System.out.println(s+"的全字符排列组合为:");allGroups(s);}//创建一个方法,用于输出指定字符串的全字符组合public static void allGroups(String s){//把字符串转换为字符数组char[] c=s.toCharArray();int l=s.length();String[] sc=new String[l];//创建一个ArrayList字符串容器alArrayList<String> al=new ArrayList<String>();//给集合al和字符串数组sc赋初始值for(int a=0;a<l;a++){sc[a]=String.valueOf(c[a]);al.add(sc[a]);}//while循环,判断条件为组合的长度是否到了最大值while(al.get(al.size()-1).length()<l){//al2用于临时存放当前长度的字符串的所有可能组合ArrayList<String> al2=new ArrayList<String>();//for循环表示,当首字符为sc[i]时,当前长度字符串的所有可能组合for(int i=0;i<l;i++){//这个增强for循环用来取al中的字符串,当满足不重复的条件时,就与首字符sc[i]进行组合for(String s1:al){if(s1.contains(sc[i])||al.get(al.size()-1).length()!=s1.length()) continue;al2.add(sc[i]+s1);}}//将当前长度字符串的所有组合存入al中,之后进入下一个长度的排列组合for(String s2 : al2) al.add(s2);}//输出al中的所有组合,由于ArrayList是有序的,因此可以按照组合字符串中字符个数按行输出int b=1;for(String s3:al){if(s3.length()!=b) System.out.println();System.out.print(s3+"\t");b=s3.length();}}}原理是先求含1个字符的子串,然后将字符串中不同字符放在首位分别与子串组合,得到长度为2的所有子串的排列组合,然后将字符串中不同字符放在首位分别与长度为2的所有子串的排列组合再组合,得到长度为3的所有子串的排列组合.以此类推。根据这个算法,我又写了个使用递归来实现的程序,代码如下。
/** * 第五题:编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如: * 原始字符串是"abc",打印得到下列所有组合情况: * "a" "b" "c" * "ab" "bc" "ca" "ba" "cb" "ac" * "abc" "acb" "bac" "bca" "cab" "cba" * @author JunZhu */import java.util.ArrayList;public class test5 {public static void main(String[] args){ //创建一个字符串,并调用allGroups方法输出其全字符组合String s="abcd";System.out.println(s+"的全字符排列组合为:");ArrayList<String> al=new ArrayList<String>();ArrayList<String> al2=new ArrayList<String>();char[] c=s.toCharArray();int l=s.length();String[] sc=new String[l];//创建一个ArrayList字符串容器al//ArrayList<String> al=new ArrayList<String>();//给集合al和字符串数组sc赋初始值for(int a=0;a<l;a++){sc[a]=String.valueOf(c[a]);al.add(sc[a]);}al2=allGroups(sc,al,al.size(),s);int b=1;for(String s3:al2){if(s3.length()!=b) System.out.println();System.out.print(s3+"\t");b=s3.length();}}//创建一个递归方法,用于输出指定字符串的全字符组合public static ArrayList<String> allGroups(String[] sc,ArrayList<String> al,int l,String s){if(l>1){ArrayList<String> al1=new ArrayList<String>();ArrayList<String> al2=new ArrayList<String>();al1=allGroups(sc,al,l-1,s);for(int i=0;i<s.length();i++){for(String s1:al1){if(s1.contains(sc[i])||al1.get(al1.size()-1).length()!=s1.length()) continue;al2.add(sc[i]+s1);}}for(String s2 : al2) al1.add(s2);return al1;}return al;}}同一个需求,可以有很多的算法实现,同一个算法,可以有不同的语言不同的形式实现。
后来我又看见一种算法。
import java.util.*;public class StringPaiLie{ public static void main(String[] args) { showPermString("abc"); } public static void showPermString(String str) { for(int i=1; i<=str.length(); i++)//str.length() { List<String> list = new ArrayList<String>(); perm(list, str.toCharArray(), 0, i); System.out.println(list); } } public static void perm(List<String> list,char[] chs,int k,int len) { if(k == chs.length) { String string = String.valueOf(chs, 0, len); if(!list.contains(string)) list.add(string); } else { for(int i=k; i<chs.length; i++) { swap(chs, i, k); perm(list,chs, k+1,len); swap(chs, i, k); } } } public static void swap(char[] chs,int i,int j) { char tem = chs[i]; chs[i] = chs[j]; chs[j] = tem; }}首先这个程序是用递归实现字符串及其子串的全排列。其实只要理解了perm方法其他的就差不多了。perm使用递归实现一个字符串的全排列。然后showPermString方法每次循环截取一定的长度,就成了它相应子串的全排列。也就是说它求子串全排列的时候,也是把整串的全排列求出来,截取从0到len的一段,因为整串的全排列肯定包含了其所有子串的全排列。但是这样效率很低。当字符串在“abcdefghi”这样长度的时候,这个程序的速度跟最上面的程序差距就很明显了。
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
0 0
- 黑马程序员_求任意字符串及其所有子串的全排列
- 求一串字符串的全排列和所有组合
- 求任意数列的全排列
- 字符串的所有全排列
- 求字符串的全排列
- 求字符串的全排列
- 求字符串的全排列
- 字符串的全排列_全组合
- 求字符串的所有最大子串
- 求字符串的所有子串
- 求字符串的所有子串
- 求字符串全排列
- 求字符串全排列
- 求字符串全排列
- 求字符串全排列
- 对任意字符串全排列
- 求取任意字符串的所有子序列
- 求任意字符串最大的重复过的子串
- WebBrowser实现Javascript和Winform代码之间实现双向通信
- hibernate映射(二) 之Hibernate单项一对多映射
- 一、启动4个线程,在控制台中输出数字,保证数字是按照顺序递增,并且没有重复数字,每隔1秒输出一个数字。
- TCP协议三次握手过程分析
- OpenCV2马拉松第9圈——再谈对比度(对比度拉伸,直方图均衡化)
- 黑马程序员_求任意字符串及其所有子串的全排列
- 数列题解
- 利用java发射 生产对象的sql插入语句
- cocos2dx 3.0 final版本 mac 创建工程
- org.apache.log4j.Logger 详解
- sed命令的使用
- OCP-1Z0-051 第121题 NATURAL JOIN自然连接
- 寄人篱下,却也不卑不亢,为了自己心中的那点情愫付出无数痴心
- android Listview的getView和convertview原理解析(三)