求个排列组合的算法问题,编程输出结果 有4个苹果,3个梨子,4个橘子排成一排,输出排列的结果。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 import java.util.HashSet;import java.util.Set;public class Permutation{ public static Set<String> set=new HashSet<String>(); public static void main(String args[]) { int a[]={1,1,1,1,2,2,2,3,3,3,3};//1是苹果 2是梨子 3是橘子 permutation(a,0); for(String t:set) { System.out.println(t); } } public static void permutation(int a[], int start) { if(start==a.length) { String temp=""; for(int p=0;p<a.length;p++) { temp=temp+a[p]; } set.add(temp); return; } for (int i = start; i < a.length; i++) { swap(a,start,i); permutation(a, start+1); swap(a,start,i); } } private static void swap(int a[],int i, int j) { int temp=a[i]; a[i]=a[j]; a[j]=temp; }}效率有点问题,11个数的排列有点多,程序10多秒 才有结果出来。 public static void main(String[] args) { char[] a = { 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c' };// a是苹果 b是梨子 c是橘子 new Permutation().zuhe(a, a.length, 0); } private void zuhe(char[] a, int n, int k) { if (n == k) { String str = new String(a); System.out.println(str); } else { for (int i = k; i < n; i++) { swap(a, k, i); zuhe(a, n, k + 1); swap(a, i, k); } } } private void swap(char[] a, int x, int y) { char temp = a[x]; a[x] = a[y]; a[y] = temp; }和楼上的有一点不同,就是可以马上看到结果,,只是程序运行完要点时间 http://blog.csdn.net/guo_rui22/archive/2008/03/20/2199732.aspx这里面有几种组合方法,看LZ想要哪种 2楼,3楼的都有问题吧?这个不是全排列的问题,相同的水果是不区分的。比方说,把第一个苹果和第二个苹果交换后,还是算同一个排列,不能重复计算。说实话,我也没有想到太好的办法,暂时用3进制的办法来做一下。假设苹果是0,橘子是1,梨子是2,那么我的循环范围就是从数字00001111222开始到22211110000的闭区间,步长为1.注意:上面的数字是“3进制”哦。然后,循环体里面,当前循环到的3进数,如果不满足4个苹果,4个橘子,3个梨子,也就是不满足4个0,4个1,3个2的话,就continue。否则的话,就输出当前的排列。好处是,不会出现,2楼,3楼的重复排列。坏处是,还是不够快,11550条有效数据,花了0.2秒多,毕竟循环了将近3的11次方。public class Test2 { /** * @param args */ public static void main(String[] args) { long timeStart = System.currentTimeMillis(); String strStart = "00001111222"; String strEnd = "22211110000"; Integer.valueOf(strStart, 3); Integer.valueOf(strEnd, 3); int count = 0; for (int i = Integer.valueOf(strStart, 3); i <= Integer.valueOf(strEnd, 3); i++) { String str = Integer.toString(i, 3); if (isOk(str)) { if (str.length() < 11) { for (int j = str.length(); j < 11; j++) System.out.print("0"); } System.out.print(str); System.out.println(); count++; } } System.out.println("count:" + count); System.out.println("used time(ms):" + (System.currentTimeMillis() - timeStart)); } public static boolean isOk(String str) { char[] chars = str.toCharArray(); short[] count = new short[3]; for (int i = 0; i < 11; i++) { if (i >= chars.length) count[0]++; else { count[chars[i] - '0']++; } if (count[0] > 4) return false; if (count[1] > 4) return false; if (count[2] > 3) return false; } return true; }}输出:000011112220000111212200001112212000011122210000112112200001121212000011212210000112211200001122121...22211001100222110100012221101001022211010100222110110002221110000122211100010222111001002221110100022211110000count:11550used time(ms):203 放到set里面就 没有重复的情况了 所以1 和2 交换 只有一个结果 ireport 静态table的问题 Struts 标签 logic:match 的用法 高人帮忙!急................. 路径加密。高手进来帮个忙 tab页面JavaScript void(0)非法跳转的问题 最近想读jdk常用包源码,各位大虾给点建议,谢谢。 6月14日带新人学j2ee的文档公开交流,大家相互学习 页面间传值的问题 请教:wml页面中如何在两个card之间传递与接收参数值?(急) 大家有什么好的有关JAVA的QQ群吗?给推荐一下好吗? 请教一下ANT WAR任务问题 Java语言和SQL语言的专业术语,您知道多少?
import java.util.HashSet;
import java.util.Set;public class Permutation
{
public static Set<String> set=new HashSet<String>();
public static void main(String args[])
{
int a[]={1,1,1,1,2,2,2,3,3,3,3};//1是苹果 2是梨子 3是橘子
permutation(a,0);
for(String t:set)
{
System.out.println(t);
}
}
public static void permutation(int a[], int start)
{
if(start==a.length)
{
String temp="";
for(int p=0;p<a.length;p++)
{
temp=temp+a[p];
}
set.add(temp);
return;
}
for (int i = start; i < a.length; i++)
{
swap(a,start,i);
permutation(a, start+1);
swap(a,start,i);
}
}
private static void swap(int a[],int i, int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}}效率有点问题,11个数的排列有点多,程序10多秒 才有结果出来。
char[] a = { 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c' };// a是苹果 b是梨子 c是橘子
new Permutation().zuhe(a, a.length, 0);
} private void zuhe(char[] a, int n, int k) {
if (n == k) {
String str = new String(a);
System.out.println(str);
} else {
for (int i = k; i < n; i++) {
swap(a, k, i);
zuhe(a, n, k + 1);
swap(a, i, k);
}
} } private void swap(char[] a, int x, int y) {
char temp = a[x];
a[x] = a[y];
a[y] = temp;
}和楼上的有一点不同,就是可以马上看到结果,,只是程序运行完要点时间
这里面有几种组合方法,看LZ想要哪种
这个不是全排列的问题,相同的水果是不区分的。
比方说,把第一个苹果和第二个苹果交换后,还是算同一个排列,不能重复计算。说实话,我也没有想到太好的办法,暂时用3进制的办法来做一下。假设苹果是0,橘子是1,梨子是2,那么我的循环范围就是从数字00001111222开始到22211110000的闭区间,步长为1.注意:上面的数字是“3进制”哦。然后,循环体里面,当前循环到的3进数,如果不满足4个苹果,4个橘子,3个梨子,也就是不满足4个0,4个1,3个2的话,就continue。否则的话,就输出当前的排列。好处是,不会出现,2楼,3楼的重复排列。坏处是,还是不够快,11550条有效数据,花了0.2秒多,毕竟循环了将近3的11次方。
public class Test2 { /**
* @param args
*/
public static void main(String[] args) { long timeStart = System.currentTimeMillis(); String strStart = "00001111222";
String strEnd = "22211110000"; Integer.valueOf(strStart, 3);
Integer.valueOf(strEnd, 3); int count = 0;
for (int i = Integer.valueOf(strStart, 3); i <= Integer.valueOf(strEnd, 3); i++) {
String str = Integer.toString(i, 3); if (isOk(str)) {
if (str.length() < 11) {
for (int j = str.length(); j < 11; j++)
System.out.print("0");
}
System.out.print(str);
System.out.println();
count++;
}
}
System.out.println("count:" + count); System.out.println("used time(ms):" + (System.currentTimeMillis() - timeStart)); } public static boolean isOk(String str) { char[] chars = str.toCharArray();
short[] count = new short[3];
for (int i = 0; i < 11; i++) {
if (i >= chars.length)
count[0]++;
else {
count[chars[i] - '0']++;
}
if (count[0] > 4)
return false;
if (count[1] > 4)
return false;
if (count[2] > 3)
return false;
}
return true;
}}输出:
00001111222
00001112122
00001112212
00001112221
00001121122
00001121212
00001121221
00001122112
00001122121
...
22211001100
22211010001
22211010010
22211010100
22211011000
22211100001
22211100010
22211100100
22211101000
22211110000
count:11550
used time(ms):203