请教,排列组合的算法

monk294 2012-03-22 02:48:13
刚有一同事问到排列组合的问题,就开始想这么实现,磨蹭了几个小时,用递归的方法貌似能解出来,但是效率奇低,不知道有没有什么好的方法呢?实现的代码在下面,希望各路大侠能够指点一下。
...全文
270 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
艳沐石 2012-03-26
  • 打赏
  • 举报
回复
这是当时回答一个帖子时,写的一段代码
需求:1,2,2,3,4,5这样的一个集合,完成它第二位不为2,3跟4不相邻的全排列


/**
* <B>name</B> 全排列测试实例
*
* @author 艳沐石
*
* @description 实现第二位不为2,3跟4不相邻的全排列
*/
public class QuanPaiLieDemo extends PaiLei {

/*
* (non-Javadoc)
* @see javase.algorithm.PaiLei#dataFilter(int[])
*/
@Override
public boolean dataFilter(int[] list) {
int index = -1;
int n = list.length;
if (n > 2 && list[1] == 2) {
return false;
}
for (int i = 0; i < n; i++) {
if (list[i] == 3) {
index = i;
break;
}
}
return index == -1 ? true :
!((index < n - 1 && list[index + 1] == 4) ||
(index > 0 && list[index - 1] == 4));
}

}

abstract class PaiLei {

private int count;

public int count() {
return count;
}

/**
* 排列算法
*
* @param list
* 排序数据
* @param k
* 移动点
* @param m
* 数据个数
*/
public void paiLie(int list[], int k, int m) {
if (k == m) {
if (dataFilter(list)) {
count++;
System.out.println(Arrays.toString(list));
}
} else {
for (int i = k; i < m; i++) {
swap(list, k, i);
paiLie(list, k + 1, m);
swap(list, k, i);
}
}
}

/**
* 限制规则方法
*
* @param list
* 排列数组
* @return 是否通过
*/
public abstract boolean dataFilter(int[] list);

private void swap(int[] datas, int i, int j) {
int t = datas[i];
datas[i] = datas[j];
datas[j] = t;
}
}
牙痴 2012-03-26
  • 打赏
  • 举报
回复
[1,2,3,4,5,6]

111111
111110
111101
111011
...
...
...

M=6 N=4 提出1个数为4的所有就是你想要的

monk294 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 awusoft 的回复:]

需要组合的话,就得改进一下了,这个只是排列的
你的M个数,如果是包含了两位数的话,又要组合的话,就得考虑一下了.如果只是一位数的话,组合还是很容易解决的

一位数的组合
for(int i=0;i<data.length;i++){
if(pre.indexOf(data[i]+"")<0)
{
……
[/Quote]
这应该是根据一个字符串包不包含来解决的,但是我觉得这并不是一种优化,在做排列组合的时候,底数一大的话程序就得跑很久了,对于这种底数有一定程序大的情况,怎么样才能快速得到答案呢?
再说,这里举的例子是数,但是在开发中往往还可能是“情况”,即M种情况中N种情况的排列组合,仅仅靠字符串来判断并不合理吧?
JieTouLangRen 2012-03-26
  • 打赏
  • 举报
回复
回溯法是比较常用的算法
此外,还有中介数法、递增进位制数法、递减进位制数法等
monk294 2012-03-23
  • 打赏
  • 举报
回复
抱歉,排列就是M个数里面取N个数进行有顺序地排列的所有情况,组合就是M个数里面取N个数(不管顺序)的所有情况,这个在高中数学里面有讲到的
[Quote=引用 4 楼 flagiris 的回复:]

具体什么排列组合啊,功能也不介绍一下,怎么优化。。
[/Quote]
蘑菇頭 2012-03-23
  • 打赏
  • 举报
回复
楼上 正解………………
awusoft 2012-03-23
  • 打赏
  • 举报
回复
需要组合的话,就得改进一下了,这个只是排列的
你的M个数,如果是包含了两位数的话,又要组合的话,就得考虑一下了.如果只是一位数的话,组合还是很容易解决的

一位数的组合
for(int i=0;i<data.length;i++){
if(pre.indexOf(data[i]+"")<0)
{
System.out.println(pre+data[i]);
}
}
awusoft 2012-03-23
  • 打赏
  • 举报
回复

public class Test {
int []data;
int num;
public Test(int []data,int num){
this.data = data;
this.getNum("",num);
}
public void getNum(String pre,int time){
if(time==1)
{
for(int i=0;i<data.length;i++){
System.out.println(pre+data[i]);;
}
}else{
int xx=time-1;
for(int i=0;i<data.length;i++){
getNum(pre+data[i],xx);
}
time--;
}
}
/**
* @param args
*/
public static void main(String[] args) {
int aa[]=new int[]{1,2,3,4,5};
new Test(aa,3);
}

}


昨天刚好写了个相似的.
菖蒲老先生 2012-03-22
  • 打赏
  • 举报
回复
具体什么排列组合啊,功能也不介绍一下,怎么优化。。
monk294 2012-03-22
  • 打赏
  • 举报
回复
代码格式乱掉了,悲剧啊
monk294 2012-03-22
  • 打赏
  • 举报
回复
代码格式乱掉了,悲剧
monk294 2012-03-22
  • 打赏
  • 举报
回复
public static void pailie(String str,List input,int stop){
if(input.size() == 1 || stop == 0){
System.out.println(str);
}else{
for(int i=0;i < input.size();i++){
List tempList = new ArrayList();
for(int j=0;j < input.size();j++){
if(j != i){
tempList.add(input.get(j));
}
}
pailie(str + "," + input.get(i),tempList,stop - 1);
}
}
}
public static void zuhe(String str,List input,int stop){
if(stop == 0){
System.out.println(str);
}else{
while(input.size() > 0){
String tempStr = input.get(0).toString();
input.remove(0);
List tempList = new ArrayList();
tempList.addAll(input);
zuhe(str+","+tempStr,tempList,stop - 1);
}
}
}

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧