[英]Create all possible binary permutations with a given number of ones in Java
我想找到给定数量的Java中所有可能的二进制排列:
例如:
x=2
, n=4
输出: 1100, 0011, 1010, 1001, 0101, 0110
我正在寻找一种优雅而又快速的方法。 你能帮助我吗? 我已经在“ 打印二进制排列列表”中测试了eboix解决方案,但是不幸的是它太慢了,因为此示例中的算法正在搜索所有2^n
二进制排列。 我想找到长度为50
或100
序列。
首先,您缺少0110
作为输出案例。
直觉上有n choose x
可能性。 您正在n
个插槽中找到x
相同项目的所有有效排列。 因此,您可以在O(1)
找到序列总数。
作为提示,请尝试简单地查找由x
个后跟n - x
零组成的位串的所有排列。
为了专门解决该问题,请尝试创建一个递归算法,该算法在每次ith
次迭代中都将1
或0
包括在内。 如果包含1
则需要减少其余字符串可使用的1's
计数。
实际上,可能有一种优雅的方法,但是没有快速的方法。 字符串排列的数量由二项式系数给出(请参阅https://en.wikipedia.org/wiki/Binomial_coefficient )。 例如,x = 10,n = 50给出了超过一千万个不同的字符串。
这只是一个基本版本,将生成您想要的输出。 请对其进行处理以使其更加准确/高效-
这不会生成所有组合,但是您将了解如何做。 当然,对于由此生成的所有可能的组合,您将必须生成所有其他可能的组合。
public class Test {
static int iter = 0;
public static void main(String args[]){
int n = 50;
int x = 5;
byte[] perms = new byte[n];
for(int i=0; i<x; i++){
perms[i] = 1;
}
print(perms);
for(int j=x-1; j>=0; j--){
for(int i=1; i<(n/2-j); i++){
iter++;
swap(perms, j, i);
}
}
}
public static void swap(byte[] perms, int pos, int by){
byte val = perms[pos+by];
perms[pos+by] = perms[pos];
perms[pos] = val;
print(perms);
val = perms[pos+by];
perms[pos+by] = perms[pos];
perms[pos] = val;
}
public static void print(byte[] perms){
System.out.println("iter = "+iter);
for(int i=0; i<perms.length; i++){
System.out.print(perms[i]);
}
System.out.println();
for(int i=perms.length-1; i>=0; i--){
System.out.print(perms[i]);
}
System.out.println();
}
}
给您的另一个灵感。 脏版本有效。 它分配了额外的数组空间(您应该调整size
),并在末尾使用String Set删除重复项。
public static void main(String[] args) {
int x = 2;
int n = 4;
Set<BigInteger> result = new LinkedHashSet<>();
for (int j = x; j > 0; j--) {
Set<BigInteger> a = new LinkedHashSet<>();
for (int i = 0; i < n - j + 1; i++) {
if (j == x) {
a.add(BigInteger.ZERO.flipBit(i));
} else {
for (BigInteger num : result) {
if (num != null && !num.testBit(i) && (i >= (n - j) || num.getLowestSetBit() >= i-1))
a.add(num.setBit(i));
}
}
}
result = a;
}
String zeros = new String(new char[n]).replace("\0", "0");
for (BigInteger i : result) {
String binary = i.toString(2);
System.out.println(zeros.substring(0, n - binary.length()) + binary);
}
}
编辑:更改了基本类型以使用BigInteger来支持更大的n,x值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.