您的位置:首页 > 编程语言 > Java开发

Java排列组合之递归调用

2013-03-26 09:24 225 查看
闲来无事在网上看到一道有趣的算法题,相信很多人都见过,原题如下:

 用1、2、2、3、4、5这六个数字,用java写一个程序,打印出所有不同的排列
 如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。 

在网上看到有很多人的答案,有用递归方法来解的,有用无向图连接遍历方法来解的,其实就是一个排列组合的问题,我觉得这道题不论用什么方法来解,最后总会回到递归上,只要将排列组合的算法实现了,那些条件限制无非就是IF ELSE的问题了,在此写下自己的方法,只为以后有需要的时候自己能有些资料复习,别一下子给搞忘了,毕竟是自己写的,熟悉!

public class Main {
public static void main(String[] args) {
Main main = new Main();
String parameter = "122345";
Set<String> set = main.action(parameter);
System.out.println("排列数量为:"+set.size());
for(String s : set){
System.out.println(s);
}
}

private boolean validate(String s){
if (s.charAt(2) == '4')
return false;
if (s.indexOf("35") >= 0 || s.indexOf("53") >= 0)
return false;
return true;
}

/**
* 递归调用方法
* @param parameter 需要排列的参数
* @return 该参数排列所有可能的数组
*         因其结果可能有数字的重复,所以采用Set去重
*/
private Set<String> action(String parameter){
//如果参数为1,则返回,
//每次递归参数的长度会减少1,这是递归的最后结点
if(parameter.length() == 1){
Set<String> set = new HashSet<String>();
set.add(parameter);
return set;
}
//方法返回数组
Set<String> resultList = new HashSet<String>();
//循环参数,将其分为两段,一段为单个字符,一段为其余的字符串
for(int i=0;i<parameter.length();i++){
//单个字符,如果12345需要排列,首先1不动,2345进行排列
String s = parameter.substring(i,i+1);
//其余的字符串
String rest = parameter.substring(0,i)+parameter.substring(i+1);
//将其余的字符串递归所得到的数组
Set<String> list = action(rest);
//将该单个字符与其余字符串的排列拼起来,既完成了以该字符占第一位,其余字符串进行排列的组合
for(String str : list){
StringBuilder sb = new StringBuilder(s.length()+str.length());
sb.append(s);
sb.append(str);

if(sb.length() == 6){
if(validate(sb.toString())){
resultList.add(sb.toString());
}
}else{
resultList.add(sb.toString());
}
}
}
return resultList;
}
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: