java全排列

Click_Me 2009-09-06 12:20:58

求一个值得推敲的JAVA全排列算法.
希望不要网上直接粘贴过来.因为我希望大家能给代码的同时教会我怎么
自己理解这个代码,自己能够写出全排列.
==== 希望大家给代码时候,能尽可能耐心的给我讲下全排列实现的思路.每次发100分..分不够了见谅.
...全文
3882 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhch152 2012-07-31
  • 打赏
  • 举报
回复
楼主比我还笨,哈哈,我都看懂了,开心啊~~~


package javabasicgrammar;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 1.================================================================
// 排列组合数字
public class Permutation {
// 方法一
public static void perm(char[] buf, int start, int end) {
if (start == end) {// 当只要求对数组中一个字母进行全排列时,只要就按该数组输出即可
for (int i = 0; i <= end; i++) {
System.out.print(buf[i]);
}
System.out.println();
} else {// 多个字母全排列
for (int i = start; i <= end; i++) {
char temp = buf[start];// 交换数组第一个元素与后续的元素
buf[start] = buf[i];
buf[i] = temp;

perm(buf, start + 1, end);// 后续元素递归全排列

// temp = buf[start];// 将交换后的数组还原
// buf[start] = buf[i];
// buf[i] = temp;
buf[i] = buf[start]; // 将交换后的数组还原
buf[start] = temp;
}
}
}

// 方法二
// 可以使用递回将问题切割为较小的单元进行排列组合,例如1 2 3 4的排列可以分为
// 1 [2 3 4],2[1 3 4],3[1 2 4],4[1 2 3]进行排列,利用旋转法,先将旋转间隔设为0,
// 将最右边的数字旋转至最左边,并逐步增加旋转的间隔,例如
// 1 2 3 4 --> 旋转1 --> 继续将右边2 3 4进行递回处理
// 2 1 3 4 --> 旋转1 2 变为 2 1 --> 继续将右边1 3 4 进行递回处理
// 3 1 2 4 --> 旋转1 2 3变为3 1 2 --> 继续将右边1 2 4进行递回处理
// 4 1 2 3 --> 旋转1 2 3 4 变为4 1 2 3 --> 继续将右边1 2 3 进行递回处理
public static void perm(int[] num, int i) { // i为第几层
if (i < num.length) { // 小于总层就旋转,旋转间隔从0开始
for (int j = i; j < num.length; j++) {
int tmp = num[j];
// 旋转该区段最右边的数字到最左边
for (int k = j; k > i; k--) {
num[k] = num[k - 1];
}
num[i] = tmp;

perm(num, i + 1);

// 还原
for (int k = i; k < j; k++) {
num[k] = num[k + 1];
}
num[j] = tmp;
}
} else { // 最后一层的时候打印
// 显示此次排序
for (int j = 0; j < num.length; j++) {
System.out.print(num[j] + " ");
}
System.out.println();
}
}

// 方法三
private static void sort(List datas, List target) {
if (target.size() == 3) { // 这个3表示要对几个字符进行全排列
for (Object obj : target)
System.out.print(obj);
System.out.println();
return;
}
for (int i = 0; i < datas.size(); i++) {
List newDatas = new ArrayList(datas);
List newTarget = new ArrayList(target);
newTarget.add(newDatas.get(i));
newDatas.remove(i);
sort(newDatas, newTarget);
}
}

public static void main(String[] args) {
// ==========================================
// int[] num = new int[4 + 1];
// for (int j = 1; j <= num.length - 1; j++) {
// num[j] = j;
// }
// perm(num, 1);
int[] num = { 1, 2, 3 };
perm(num, 0);
// ==========================================
System.out.println();
char buf[] = { 'a', 'b', 'c' };
perm(buf, 0, buf.length - 1);
// ==========================================
System.out.println();
String[] datas = new String[] { "a", "b", "c" };
sort(Arrays.asList(datas), new ArrayList());
}
}

milk713785 2011-04-23
  • 打赏
  • 举报
回复
好复杂,让我想想。。。
asusaltecsrs 2011-04-02
  • 打赏
  • 举报
回复
楼主的算法很经典,
shenlongenjoyjava 2010-09-12
  • 打赏
  • 举报
回复
在看数据结构,上面有这方面的课后题,虽然不太懂,还是借鉴学习了。谢谢各位了!
scuhank 2010-06-19
  • 打赏
  • 举报
回复
说错了,应该说跟N皇后问题有很大的相似之处,不完全一样
scuhank 2010-06-19
  • 打赏
  • 举报
回复
我在做吸血鬼数字的时候,中间用到了全排列的方法。我写的全排列跟1楼的思路一样,排列总数也是对的,但是存在重复的情况。不过,字典序好像就没有重复。
其实,整数1~n的全排列跟N皇后问题完全一样。不是1~n的整数问题(即字母全排列或非严格的1~n整数)也可以化为1~n进行间接处理。
bigbug9002 2009-09-07
  • 打赏
  • 举报
回复
递归是自己调用自己,流程不太好画啊。
huangqibing0626 2009-09-07
  • 打赏
  • 举报
回复
呵呵···恰好我们老师正在讲这个东东,具体我也没有怎么听懂,不过我的理解是:譬如1,2,3,4
第一步:1,2,3,4 因为第一个数只跟自己交换
第二步:1,2,4,3 1,2都提炼出来了,只对3,4排列
第三步:1,3,2,4 数组还原,第二个和下一个交换
第四步:1,3,4,2 思想同第二步
第五步:1,4,3,2 数组还原成1,2,3,4,第二个和第四个交换
第六步:1,4,2,3 思想同第二步

下面以2,3,4开头的也就同理了···
24K純帥 2009-09-07
  • 打赏
  • 举报
回复

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FullSort {
//将NUM设置为待排列数组的长度即实现全排列
private static int NUM = 3;

/**
* 递归算法:将数据分为两部分,递归将数据从左侧移右侧实现全排列
*
* @param datas
* @param target
*/

private static void sort(List datas, List target) {
if (target.size() == NUM) {
for (Object obj : target)
System.out.print(obj);
System.out.println();
return;
}
for (int i = 0; i < datas.size(); i++) {
List newDatas = new ArrayList(datas);
List newTarget = new ArrayList(target);
newTarget.add(newDatas.get(i));
newDatas.remove(i);
sort(newDatas, newTarget);
}
}

public static void main(String[] args) {
String[] datas = new String[] { "a", "b", "c", "d" };
sort(Arrays.asList(datas), new ArrayList());
}

}
moneyNUMBER_1 2009-09-07
  • 打赏
  • 举报
回复
java中有排序方法sorf()自己按首字母顺序数字从小到大
Click_Me 2009-09-06
  • 打赏
  • 举报
回复

谢谢楼上的.大家有好的理解方式.希望多提出!
justinavril 2009-09-06
  • 打赏
  • 举报
回复
public class AllSort{  
public static void main(String[] args) {
char buf[]={'a','b','c'};

perm(buf,0,buf.length-1);
}
public static void perm(char[] buf,int start,int end){
if(start==end){//当只要求对数组中一个字母进行全排列时,只要就按该数组输出即可
for(int i=0;i<=end;i++){
System.out.print(buf[i]);
}
System.out.println();
}
else{//多个字母全排列
for(int i=start;i<=end;i++){
char temp=buf[start];//交换数组第一个元素与后续的元素
buf[start]=buf[i];
buf[i]=temp;

perm(buf,start+1,end);//后续元素递归全排列

temp=buf[start];//将交换后的数组还原
buf[start]=buf[i];
buf[i]=temp;
}
}
}
}


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/justinavril/archive/2008/08/02/2758636.aspx
Click_Me 2009-09-06
  • 打赏
  • 举报
回复
但现在主要是 我没理解 怎么实现的全排列 大伙能不能用 a,b,c这3个数 把那个代码的解析流程给说下
bigbug9002 2009-09-06
  • 打赏
  • 举报
回复
其它的排列求法就不贴了.贪多无益。只弄会一个就可以了.

n个数据求全排列,递归的思路好多个吧。猴子给的算法算其中的一种。

这种递归的思路是:分别求第i个数据排在第一位的时,其它n-1个数据的全排列。求n-1个数据的全排列与求n个数据的全排列求法相同。当只有一个数据时,是递归的出口。
Click_Me 2009-09-06
  • 打赏
  • 举报
回复
按楼上那么说 0交换1 1交换2 2交换3 3交换4 4交换5 这样就完毕了 根本就没有全排列,..
justinavril 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 click_me 的回复:]
Java code
我想问下这个递归和for循环的运行顺序
比如第一次初始化perm(buf,0,buf.length-1);
那么下面的for循环就为for(int i=0; i<=2; i++){// 这里进行一次交换(略)perm(buf,start+1,end);//从起点之后,递归数组.那么这一递归//就又重新执行函数了.也就是每次for循环虽然<=2但也就执行了一次//这样怎么进行¡­
[/Quote]
比如我开始start是0,end是数组的最后一位,是5,那么第一次执行时,是perm(buf, 0, 5),然后交换元素0和元素1,此时执行perm(buf, 0+1, 5),这个方法里,交换元素1和2(因为start是0+1,也就是1了),然后依次循环下去。。。
cqhweb 2009-09-06
  • 打赏
  • 举报
回复
非常值学习与借鉴..
Click_Me 2009-09-06
  • 打赏
  • 举报
回复

我想问下这个递归和for循环的运行顺序
比如第一次初始化perm(buf,0,buf.length-1);
那么下面的for循环就为
for(int i = 0; i <=2; i++){
// 这里进行一次交换(略)
perm(buf,start+1,end);//从起点之后,递归数组.那么这一递归
//就又重新执行函数了.也就是每次for循环虽然<=2但也就执行了一次
//这样怎么进行的全排列


}
justinavril 2009-09-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 click_me 的回复:]
Java code
justinavril#1
如果有耐心 希望你能把你的思路剖析下.授人以鱼不如授人以渔...谢谢了
[/Quote]
这是一个递归算法,start和end游标控制你要进行递归的位置。我就解释下for循环里的每一句吧:
for(int i=start;i<=end;i++){//从第一个你要全排列的数开始遍历数组,称该元素为起点吧  
char temp=buf[start];//将起点存到temp变量中
buf[start]=buf[i];//将起点赋值为之后那个元素
buf[i]=temp; //起点之后的元素赋值为temp,也就是起点。这样就完成了起点和起点之后元素的交换

perm(buf,start+1,end);//从起点之后,递归数组

temp=buf[start];//将交换后的数组还原
buf[start]=buf[i];
buf[i]=temp;
}
Click_Me 2009-09-06
  • 打赏
  • 举报
回复

尤其是多数组排序那块 也就3块代码 但我现在理解不太好
加载更多回复(3)

62,614

社区成员

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

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