【问题标题】:JavaScript - efficiently create array of binaries strings with number of bits setJavaScript - 有效地创建具有位数的二进制字符串数组
【发布时间】:2021-06-11 20:20:40
【问题描述】:

两个参数

  1. 字符串长度
  2. 设置的位数

示例输入:5、2

输出:[“00011”、“00101”、“00110”、“01001”、“01010”、“01100”、“10001”、“10010”、“10100”、“11000”]

示例输入:7、3

输出:[“0000111”、“0001011”、“0001101”、“0001110”、“0010011”、“0010101”、“0010110”、“0011001”、“0011010”、“0011100”、“0100011”、 “0100101”、“0100110”、“0101001”、“0101010”、“0101100”、“0110001”、“0110010”、“0110100”、“0111000”、“1000011”、“1000101”、“1000110”、“10010” ”、“1001010”、“1001100”、“1010001”、“1010010”、“1010100”、“1011000”、“1100001”、“1100010”、“1100100”、“1101000”、“1110000”]

我创建的 Eager 算法从长度超过 20 开始变得非常低效

const getBinaries = (length, numberOfBitsSet) => {
    const ones = new Array(length).fill(1).join('');
    const max = parseInt(ones, 2) + 1;
    const binaries = [];
    for (let i = 1; i < max; i++) {
        let bin = parseInt(i).toString(2);
        const match = bin.match(/1/g);
        if (!match || match.length !== numberOfBitsSet) {
            continue;
        }
        const strLen = bin.split('').length;
        const zeros = new Array(length - strLen).fill(0).join('');
        bin = `${zeros}${bin}`;
        binaries.push(bin);
    }
    return binaries;
};

【问题讨论】:

    标签: javascript bitwise-operators bit bit-shift


    【解决方案1】:

    我认为这是一个组合问题。可以将其解释为整数,它恰好是numberOfBitsSet 2 的幂之和。所以一个算法可能是这样的:

    1. 创建从2^02^(length - 1) 的所有二的幂的列表。
    2. 从该集合中选择恰好包含numberOfBitsSet 的所有子集。
    3. 总结前几组的元素。
    4. 使用num.toString(2)将数字转换为二进制字符串
    5. 用零向左填充结果,这样所有结果都包含length 字符。

    但是,对于默认的 JavaScript 数字类型,这只会扩展到 51 的长度(默认数字类型的整数精度大约以 2^51 结束)。之后,您可能需要求助于新的BigInt type

    【讨论】:

    • 不是所有 2 的幂都只包含定义的 1 位吗?我认为您可能希望在 1 和 2 之间添加一个步骤。我同意这是一种更好的通用方法!
    • @nico 是的,(1) 中的集合总是只包含一个位集合,这就是为什么你在 (2) 中选择 numberOfBitsSet-其中许多并将它们加到 (3) .这应该可以让您获得设置的位数。
    【解决方案2】:

    您可以使用 Generator 并创建索引数组并在最后一步返回二进制字符串。

    function* g(length, bits, pattern = [], i = 0) {
        if (!bits) {
            yield Array.from({ length }, (_, i) => +pattern.includes(i)).join('');
            return;
        }
        while (i < length) yield* g(length, bits - 1, [...pattern, i], ++i);
    }
    
    console.log([...g(5, 2)]);
    console.log([...g(7, 3)]);
    console.log([...g(21, 5)]);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 太棒了,非常优雅!
    猜你喜欢
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2019-01-16
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    相关资源
    最近更新 更多