在Java中创建布尔数组的每个组合

时间:2014-07-08 19:28:09

标签: java arrays

我写的程序需要一个接收三个整数的方法(比如nsk)并返回一个带{{1的布尔数组} {true},s false值,n-sk0之间的变量)确定其顺序。例如,常量为n choose kn=5s=2,我们可以得到数组

k=1

[true, true, false, false, false] n=7s=3

k=2

具体而言,[true, true, false, true, false, false, false] 只要其内射,即k的不同值导致不同的组合,就会确定什么顺序无关紧要。

我的一个想法是使用k来转换' k'转换为二进制字符串然后将Integer.toBinaryString(int i)1转换为0true,但不幸的是我没有看到一个简单的方法来让号码false的{​​{1}}由1确定。有没有人知道一个好方法或能告诉我正确的方向?

3 个答案:

答案 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))