我希望在Java中找到具有给定数量的二进制排列的所有二进制排列:
举个例子:
x=2
,n=4
输出:1100, 0011, 1010, 1001, 0101, 0110
我正在寻找一种优雅而快速的方法来做到这一点。你能帮助我吗?
我已经在Print list of binary permutations中测试了eboix解决方案,但遗憾的是它太慢了,因为此示例中的算法正在搜索所有2^n
二进制排列。
我想查找长度为50
或100
的序列。
答案 0 :(得分:0)
首先,您将0110
作为输出案例丢失。
相当直观,有n choose x
种可能性。您在x
个总时段中找到n
个相同项目的所有有效排列。因此,您可以在O(1)
中找到序列总数。
作为提示,请尝试简单地查找由x
个字符串组成的位串的所有排列,后跟n - x
个零。
要专门解决此问题,请尝试创建一个递归算法,该算法在每ith
次迭代时决定包含1
或0
。如果包含1
,则需要递减可用于其余字符串的1's
计数。
答案 1 :(得分:0)
实际上,可能有一种优雅的方式,但没有快速的方法来做到这一点。字符串排列的数量由二项式系数给出(参见https://en.wikipedia.org/wiki/Binomial_coefficient)。例如,x = 10,n = 50给出超过1000万个不同的字符串。
答案 2 :(得分:0)
这是一个可以生成所需输出的基本版本。请努力使其更准确/更有效 -
这不会生成所有组合,但您将了解如何执行此操作。当然,对于由此产生的所有可能组合,您将必须生成所有其他可能的组合。
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();
}
}
答案 3 :(得分:0)
另一个灵感来自你。一个有用的脏版本。它分配额外的数组空间(你应该调整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值。