package LanQiao.day06;
/**
* @program: ShuJuJieGou
* @author: GONG-Q
* @create: 2021-10-13 18:17
**/
public class 排列 {
//不重复的字符串的全排列
public static void string_full_permutation(String str,StringBuffer buffer){
//结束条件
if(buffer.length()==str.length()){
System.out.println(buffer.toString());
return;
}
//递归体的部分
for (int i = 0; i < str.length(); i++) {
//判断是否重 一次只能有一个
if(buffer.toString().indexOf(str.charAt(i))!=-1) continue; //如果找到了就说明已经存在过了所以删除
buffer.append(str.charAt(i));
string_full_permutation(str,buffer);
buffer.deleteCharAt(buffer.length()-1);
}
}
//有重复的字符串的排列
/**
* 对于有重复的算法来说 很重要的一点就是首先要对传入的进行排序 这样的话更好筛选 如果这一位与上一位相同那么必定就是重复的需要减枝
* 因为有重复的 不能用一般的条件来判断是不是已经访问过了 所以需要使用的是一个数组来表示这个点是否被访问过
* 也不要忘记进行回溯
* @param repeatStr
* @param buffer
* @param visit
*/
public static void repeat_string_permutation(String repeatStr,StringBuffer buffer,boolean[] visit){
if(repeatStr.length()==buffer.length()){
System.out.println(buffer.toString());
return;
}
for (int i = 0; i < repeatStr.length(); i++) {
// if(buffer.toString().indexOf(repeatStr.charAt(i))!=-1) continue;
if(visit[i]==true) continue;
//因为有重复的元素 所以需要减枝操作
if(i-1>=0&&repeatStr.charAt(i)==repeatStr.charAt(i-1)&&!visit[i-1]) continue;
buffer.append(repeatStr.charAt(i));
visit[i]=true;
repeat_string_permutation(repeatStr,buffer,visit);
buffer.deleteCharAt(buffer.length()-1);
visit[i]=false;
}
}
//组合的算法
/**
*
* @param n 需要组合的
* @param k 需要组合的数量
* @param start 开始的位置
* @param buffer 存放结果
*/
public static void combine(int n,int k,int start,StringBuffer buffer){
if(k==0){
System.out.println(buffer.toString());
return;
}
//递归的部分
for (int i = start; i <= n; i++) {
buffer.append(i);
combine(n,k-1,i+1,buffer);
buffer.deleteCharAt(buffer.length()-1);
}
}
public static void main(String [] args){
// string_full_permutation("ABC",new StringBuffer());
// repeat_string_permutation("aab",new StringBuffer(),new boolean[3]);
combine(4,2,1,new StringBuffer());
}
}
还有另外一种方式:
就是通过swap的方式也可以进行排列
package LanQiao.day06;
import java.util.List;
import java.util.Vector;
/**
* @program: ShuJuJieGou
* @author: GONG-Q
* @create: 2021-10-13 16:17
*
* 由不同字母构成的串 求全排
**/
public class 排列组合 {
public static void main(String [] args){
String s="ABD";
System.out.println(full_permutation(s));
}
/**
* 字符数组的排列方式
* @param chars
* @param a
* @param b
*/
public static void paiLie(char[] chars,int a,int b){
//递归结束条件就是排序的串只有一个字母的时候
if(a==b){
for (int i = 0; i < chars.length; i++) {
System.out.print(chars[i]);
}
}
//递归部分
for (int i = a; i < b; i++) {
swap(chars,a,i);
paiLie(chars,a+1,b);
swap(chars, a, i);
}
}
//交换函数
public static void swap(char[] a,int i,int j){
char temp=a[i];
a[i]=a[j];
a[j]=temp;
}
//字符串的排列方式
public static List<String> full_permutation(String str){
List<String> List = new Vector<>();
//通过字符串的方式
if(str.length()==1){
List.add(str);
return List;
}
//递归体的部分
for (int i = 0; i < str.length(); i++) {
char cur = str.charAt(i);//用于临时存放
//再创建一个用于存放除去I的之外的排列
List<String> list = new Vector<>();
list=full_permutation(str.substring(0,i)+str.substring(i+1));
//然后将I加到前面
for (int j = 0; j < list.size(); j++) {
List.add(""+cur+list.get(j));
}
}
return List;
}
}