juedui520 2021-02-27 14:04 采纳率: 100%
浏览 80
已采纳

如何快速列出63位二进制中有36个1和27个0的所有二进制组合

000000000000000000000000000000000000000000000000000000000000000

111111111111111111111111111111111111111111111111111111111111111

以上是63位2进制,用哪种方法可以不用遍历列出所有的36个1和27个0的所有二进制组合

例如:

第一组

000000000000000000000000000111111111111111111111111111111111111

第二组....第三组....

求大神帮忙。。。

  • 写回答

1条回答 默认 最新

  • 糖气包 2021-03-01 23:39
    关注

    这是个简单的排列组合,只是你的数据太大,很可能内存扛不住,下面有两种简单的方式处理这种问题 (Java 实现)。

    1、暴力迭代搜索

    public static List<String> solution0(int zeroNumber, int oneNumber) {
        if ((zeroNumber | oneNumber) < 0) {
            throw new IllegalArgumentException(String.format("The number of zero or one is negative : zero = %s, one = %s.", zeroNumber, oneNumber));
        }
        int sequenceLen = zeroNumber + oneNumber;
        if (sequenceLen == zeroNumber || sequenceLen == oneNumber) {
            String sequence = new String(IntStream.range(0, sequenceLen).map(i -> zeroNumber == 0 ? '1' : '0').toArray(), 0, sequenceLen);
            return Collections.singletonList(sequence);
        }
        /* C(m, m + n),计算总数,提前初始化,避免扩容,不过可能出现溢出的情况。 */
        List<String> sequences = new ArrayList<>();
        char[] values = new char[sequenceLen];
        Arrays.fill(values, '0');
        helper(0, oneNumber, values, 0, sequences);
        return sequences;
    }
    
    private static void helper(int oneCount, int oneNumber, char[] values, int pos, List<String> sequences) {
        if (oneNumber - oneCount > values.length - pos) {
            return;
        }
        if (oneCount == oneNumber) {
            sequences.add(new String(values));
            return;
        }
        values[pos] = '1';
        helper(oneCount + 1, oneNumber, values, pos + 1, sequences);
        values[pos] = '0';
        helper(oneCount, oneNumber, values, pos + 1, sequences);
    }

    2、针对零和一的数量和小于等于 64 的优化版本

    public static String[] solution1(int zeroNumber, int oneNumber) {
        final int sequenceLen = zeroNumber + oneNumber;
        if ((zeroNumber | oneNumber) < 0 || sequenceLen > 64) {
            throw new IllegalArgumentException(String.format("The number of zero or one are abnormal : zero = %s, one = %s.", zeroNumber, oneNumber));
        }
        if (sequenceLen == zeroNumber || sequenceLen == oneNumber) {
            String sequence = new String(IntStream.range(0, sequenceLen).map(i -> zeroNumber == 0 ? '1' : '0').toArray(), 0, sequenceLen);
            return new String[]{sequence};
        }
        final int resultNumber = (int) MathUtils.nchoosek(sequenceLen, oneNumber);
        long[][] binaryValues = new long[resultNumber][2];
        /* 索引 0 记录二进制值,索引 1 记录 1 的数量 */
        binaryValues[0] = new long[]{0, 0};
        binaryValues[1] = new long[]{1, 1};
        for (int i = 1, count = 2; i < sequenceLen; ++i) {
            int index = count;
            for (int j = 0; j < count; ++j) {
                long value = binaryValues[j][0];
                long oneCount = binaryValues[j][1];
                if (oneCount == oneNumber) {
                    continue;
                }
                if (oneNumber - oneCount == sequenceLen - i) {
                    binaryValues[j][0] = value | (1L << i);
                    binaryValues[j][1] = oneCount + 1;
                    continue;
                }
                binaryValues[index++] = new long[]{value | (1L << i), oneCount + 1};
            }
            count = index;
        }
        String[] result = new String[resultNumber];
        for (int i = 0; i < resultNumber; ++i) {
            /* 简单转换 long 数值为二进制字符串 */
            char[] chars = new char[(int) sequenceLen];
            for (int j = 0; j < sequenceLen; ++j) {
                chars[j] = (char) (((binaryValues[i][0] >>> j) & 1) + '0');
            }
            result[i] = new String(chars);
            binaryValues[i] = null;
        }
        return result;
    }
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端