我写的程序需要一个接收三个整数的方法(比如n
,s
和k
)并返回一个带{{1的布尔数组} {true},s
false值,n-s
(k
和0
之间的变量)确定其顺序。例如,常量为n choose k
,n=5
和s=2
,我们可以得到数组
k=1
或[true, true, false, false, false]
,n=7
和s=3
k=2
具体而言,[true, true, false, true, false, false, false]
只要其内射,即k
的不同值导致不同的组合,就会确定什么顺序无关紧要。
我的一个想法是使用k
来转换' k'转换为二进制字符串然后将Integer.toBinaryString(int i)
和1
转换为0
和true
,但不幸的是我没有看到一个简单的方法来让号码false
的{{1}}由1
确定。有没有人知道一个好方法或能告诉我正确的方向?
答案 0 :(得分:2)
这是alternative I mentioned。它迭代所有n位数字,只设置k位。
/**
* Iterates all bit patterns containing the specified number of bits.
*
* See "Compute the lexicographically next bit permutation"
* http://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
*
* @author OldCurmudgeon
*/
public class BitPattern implements Iterable<BigInteger> {
// Useful stuff.
private static final BigInteger ONE = BigInteger.ONE;
private static final BigInteger TWO = ONE.add(ONE);
// How many bits to work with.
private final int bits;
// Value to stop at. 2^max_bits.
private final BigInteger stop;
// Should we invert the output.
private final boolean not;
// All patterns of that many bits up to the specified number of bits - invberting if required.
public BitPattern(int bits, int max, boolean not) {
this.bits = bits;
this.stop = TWO.pow(max);
this.not = not;
}
// All patterns of that many bits up to the specified number of bits.
public BitPattern(int bits, int max) {
this(bits, max, false);
}
@Override
public Iterator<BigInteger> iterator() {
return new BitPatternIterator();
}
/*
* From the link:
*
* Suppose we have a pattern of N bits set to 1 in an integer and
* we want the next permutation of N 1 bits in a lexicographical sense.
*
* For example, if N is 3 and the bit pattern is 00010011, the next patterns would be
* 00010101, 00010110, 00011001,
* 00011010, 00011100, 00100011,
* and so forth.
*
* The following is a fast way to compute the next permutation.
*/
private class BitPatternIterator implements Iterator<BigInteger> {
// Next to deliver - initially 2^n - 1
BigInteger next = TWO.pow(bits).subtract(ONE);
// The last one we delivered.
BigInteger last;
@Override
public boolean hasNext() {
if (next == null) {
// Next one!
// t gets v's least significant 0 bits set to 1
// unsigned int t = v | (v - 1);
BigInteger t = last.or(last.subtract(BigInteger.ONE));
// Silly optimisation.
BigInteger notT = t.not();
// Next set to 1 the most significant bit to change,
// set to 0 the least significant ones, and add the necessary 1 bits.
// w = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
// The __builtin_ctz(v) GNU C compiler intrinsic for x86 CPUs returns the number of trailing zeros.
next = t.add(ONE).or(notT.and(notT.negate()).subtract(ONE).shiftRight(last.getLowestSetBit() + 1));
if (next.compareTo(stop) >= 0) {
// Dont go there.
next = null;
}
}
return next != null;
}
@Override
public BigInteger next() {
last = hasNext() ? next : null;
next = null;
return not ? last.not() : last;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String toString() {
return next != null ? next.toString(2) : last != null ? last.toString(2) : "";
}
}
public static void main(String[] args) {
// Generates 1, 10, 100. One bit set in a 3-bit number.
int bits = 1;
int max = 3;
System.out.println("BitPattern(" + bits + ", " + max + ")");
for (BigInteger i : new BitPattern(bits, max)) {
System.out.println(i.toString(2));
}
}
}
答案 1 :(得分:1)
我认为您要查找的关键字是combinadic
。
Here是我在数学页面回答我的一个问题时最终想出来的。
实质上,您可以使用此技术在n位数字序列中选择第k个数字。
关于它如何在公认的答案here中起作用,有一个很好的叙述。
但是,如果你只是想要迭代k位数,那就有other more efficient种方式。
答案 2 :(得分:-1)
如何使用k对数组进行混洗以播种随机性?
myArray = [true,true,true,false,false,...]
Collections.shuffle(myArray, new Random(k))