递归专题-排列组合问题
2018-01-17 10:23
295 查看
问题描述:输入一个字符串,然后将字符串所有字符排列组合,输出排列组合后的所有可能。
思路:把一个字符串看成两个部分,第一部分是它的第一个字符,第二部分是它后边的所有字符。求所有排列的过程可看做两步,第一步求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换(注:并不是一次找出来全部,而是找出来一个,就执行第二步,找出以这个字符开始的全部排列,第一步通过循环遍历实现)。
第二步固定第一个字符,求后面所有字符的排列,此时仍把后面所有字符分成上述的两部分,然后递归处理。找出全部排列后还要之前交换的字符交换回去,保证找到的第一个位置不重复。注意本题考虑了去重复问题,即相同排列只显示一次,方法是在交换第一个元素和后边的元素时,如果值相等就不交换,或者后边这个值在之前位置出现过(说明曾经交换过),也不交换。
package zhuanti.digui;
import java.util.Arrays;
import java.util.Scanner;
/**
* 给一个字符串,然后把这个字符串重新排列组合,列出所有可能
*/
public class Pailiewenti {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入要进行全排列的字符串:");
String s=sc.nextLine();
Permutation(s.toCharArray());
sc.close();
}
public static void Permutation(char[] str){
if(str==null)
return;
int begin=0;
Permutation(str, begin);
}
public static void Permutation(char[] str,int begin){
if(begin+1==str.length){//遍历完一遍字符串,打印输出一次,返回
//System.out.println(String.valueOf(str));
System.out.println(Arrays.toString(str));
}
else{
for(int i=begin;i<str.length;i++){
if(notSame(str,begin,i)){//去重判断,如果当前字符和后边的字符一样,或者后边字符在之前出现过,不交换。第一次自己和自己换除外。
//1,可能出现在第一个位置的字符,即交换第一个字符和后边所有字符,第一次是自己和自己交换
swap(str,begin,i);
//2,固定第一个字符,递归求后面所有字符的排列
Permutation(str, begin+1);
//3,递归处理完后边的字符后,记得把前边交换的字符再换回来,保证第一个位置的字符不重复
swap(str,begin,i);
}
}
}
}
public static boolean notSame(char[] str,int begin,int end){
for(int j=begin;j<end;j++){
if(str[j]==str[end]){
return false;
}
}
return true;
}
public static void swap(char[] str,int a,int b){
char temp = str[a];
str[a] = str[b];
str[b] = temp;
}
}
思路:把一个字符串看成两个部分,第一部分是它的第一个字符,第二部分是它后边的所有字符。求所有排列的过程可看做两步,第一步求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换(注:并不是一次找出来全部,而是找出来一个,就执行第二步,找出以这个字符开始的全部排列,第一步通过循环遍历实现)。
第二步固定第一个字符,求后面所有字符的排列,此时仍把后面所有字符分成上述的两部分,然后递归处理。找出全部排列后还要之前交换的字符交换回去,保证找到的第一个位置不重复。注意本题考虑了去重复问题,即相同排列只显示一次,方法是在交换第一个元素和后边的元素时,如果值相等就不交换,或者后边这个值在之前位置出现过(说明曾经交换过),也不交换。
package zhuanti.digui;
import java.util.Arrays;
import java.util.Scanner;
/**
* 给一个字符串,然后把这个字符串重新排列组合,列出所有可能
*/
public class Pailiewenti {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入要进行全排列的字符串:");
String s=sc.nextLine();
Permutation(s.toCharArray());
sc.close();
}
public static void Permutation(char[] str){
if(str==null)
return;
int begin=0;
Permutation(str, begin);
}
public static void Permutation(char[] str,int begin){
if(begin+1==str.length){//遍历完一遍字符串,打印输出一次,返回
//System.out.println(String.valueOf(str));
System.out.println(Arrays.toString(str));
}
else{
for(int i=begin;i<str.length;i++){
if(notSame(str,begin,i)){//去重判断,如果当前字符和后边的字符一样,或者后边字符在之前出现过,不交换。第一次自己和自己换除外。
//1,可能出现在第一个位置的字符,即交换第一个字符和后边所有字符,第一次是自己和自己交换
swap(str,begin,i);
//2,固定第一个字符,递归求后面所有字符的排列
Permutation(str, begin+1);
//3,递归处理完后边的字符后,记得把前边交换的字符再换回来,保证第一个位置的字符不重复
swap(str,begin,i);
}
}
}
}
public static boolean notSame(char[] str,int begin,int end){
for(int j=begin;j<end;j++){
if(str[j]==str[end]){
return false;
}
}
return true;
}
public static void swap(char[] str,int a,int b){
char temp = str[a];
str[a] = str[b];
str[b] = temp;
}
}
相关文章推荐
- 字符串的全排列和组合递归非递归--排列组合扩展问题
- 递归求解几类排列组合问题(三、非重复组合排列)
- 递归-计算排列组合问题
- 多个数组间元素排列组合问题求解(Java实现) 标签: 递归排列组合循环
- 递归求解几类排列组合问题(四、普通选择性组合排列)
- 【专题】计数问题(排列组合,容斥原理,Prufer序列)
- C/C++ 排列组合问题(递归)
- 字符串的全排列和组合递归非递归--排列组合扩展问题
- 递归实现排列组合问题
- 递归求解几类排列组合问题(四、普通选择性组合排列)
- 用递归写排列组合问题
- 递归实现排列组合问题
- 递归求解几类排列组合问题(五、生成全子集组合排列)
- 递归解决问题的几种类型的排列(二、完整的组合安排)
- 全排列问题、八皇后问题、组合问题的递归解法
- 递归求解几类排列组合问题(六、非重复生成全子集组合排列)
- 递归-排列组合问题
- 递归求解几类排列组合问题(一、类循环组合排列)
- 递归求解几类排列组合问题(二、全组合排列)
- Java 非递归实现的排列组合中的平均分组问题