之前学习递归算法的时候一直来不及总结一下,也花了一些时间去理解排列组合中的实现问题,现在总结一下,希望对大家能有帮助
1. 排列问题
问题:由a、b、c三个字母随机组成的所有排列情况
思路:首先 先确定第一位字母,例如确定了a,则情况就变成了a与剩下两位字母的随机组合,这里就是递归实现,自身实现自身方法。当列出了所以以a为启示的情况后,a与b交换 ,交换后仍然是递归方法。之后a与c进行交换。注意a和b递归完,恢复原来的位置,然后再让 a与c换位子,不然换的则是b与c。
下面是代码
package test;
public class pailie {
public static void p(char[] array, int index){
char temp;
if(index==array.length){
System.out.println(array);
return;
}
if(array.length==0||index<0||index>array.length){
return;
}
for(int j=index;j<array.length;j++){
temp=array[j];
array[j]=array[index];
array[index]=temp;
p(array, index+1);
temp=array[j];
array[j]=array[index];
array[index]=temp;
}
}
public static void main(String[] args) {
char[] chars={'a','b','c'};
p(chars,0);
}
}
2. 组合问题
问题:有a,b,c三个字母,让它们随机组合,可以有[a],[a,b],[a,c]等许多组合结果
思路:用一个arraylist储存数组结果,每次取多少个字母设置为number参数进行循环,number可以为1,2,3。即随机从组合里抽1个字母/2个字母/3个字母。第三个参数是从第几个字母开始取number个字母,如果从a开始取字母,则组合情况包含两种。一种就是包含a参数的,剩下的number-1随机组合(递归思想)。另一种就是不包含参数a的,剩下的number字母随机组合(递归思想)。因此实现起来的代码如下
package test;
import java.util.ArrayList;
import java.util.List;
public class zuhe {
public void p(char[] arrays, int begin, int number, List<Character> list){
if(number==0){
System.out.println(list.toString());
return;
}
if(begin==arrays.length){
return;
}
list.add(arrays[begin]);
p(arrays, begin+1, number-1,list);
list.remove((Character)arrays[begin]);
p(arrays, begin+1, number,list);
}
public static void main(String[] args) {
char[] arrays={'a','b','c'};
zuhe zuhe=new zuhe();
List<Character> list= new ArrayList();
for(int number=1;number<=arrays.length;number++){
zuhe.p(arrays,0,number,list);
}
}
}
3. 排列去重问题
问题:有数字12234,对它们随机进行排列,不允许有重复
思路:采用排列的递归思想,在这基础之上,对交换数字时进行判断,如果要交换的数字在之前已存在,则不交换,返回false;如果要交换的数字不存在,则交换,继续递归。改进后的代码如下
package test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
public class pailie1 {
static int k=0;
static HashSet<char[]> set=new HashSet<char[]>();
static ArrayList<Character> list=new ArrayList<Character>();
public boolean isSwap(char[] num , int i ,int j)
{
for(int index = i;index<j;index++)
{
if(num[index]==num[j])
return false;
}
return true;
}
public void p(char[] array,int index){
char temp;
if(index<0||index>array.length){
return;
}
if(index==array.length){
System.out.println(array);
// set.add(array);
k++;
}
for(int j=index;j<array.length;j++){
if(isSwap(array, index, j)){
temp=array[j];
array[j]=array[index];
array[index]=temp;
p(array, index+1);
temp=array[j];
array[j]=array[index];
array[index]=temp;
}else{
continue;
}
}
}
public static void main(String[] args) {
String s="12234";
char[] c=s.toCharArray();
pailie1 pailie=new pailie1();
pailie.p(c,0);
System.out.println(k);
}
}
最后一行输出了总数,运用数学计算排列问题总共有60中,总数验证正确性,也为60。
4. 组合中的去重问题
问题:有数字1223,让它们两两组合,不能有重复。
思路:采用hashset加入到组合算法中,代码如下
package test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class zuhe1 {
static int k=0;
static HashSet<String> set;
public void p(char[] arrays,int begin, int number, ArrayList<Character> list){
if(number==0){
// System.out.println(list.toString());
k++;
set.add(list.toString());
return;
}
if(begin==arrays.length){
return;
}
list.add(arrays[begin]);
p(arrays, begin+1, number-1, list);
list.remove((Character)arrays[begin]);
p(arrays, begin+1, number, list);
}
public static void main(String[] args) {
String s="1223";
char[] arrays=s.toCharArray();
zuhe1 zuhe1=new zuhe1();
ArrayList<Character> list=new ArrayList<Character>();
for(int number=1;number<arrays.length+1;number++){
set=new HashSet<String>();
zuhe1.p(arrays,0,number,list);
Iterator<String> it=set.iterator();
while(it.hasNext()){
String a=it.next();
System.out.println(a);
}
}
}
}
以上是我对java中排列组合的一些理解,也许有更好的算法,也请大神指教。