【问题标题】:Is there a built-in python function to count bit flip in a binary string?是否有内置的 python 函数来计算二进制字符串中的位翻转?
【发布时间】:2021-12-11 07:47:36
【问题描述】:

是否有内置的 python 函数来计算二进制字符串中的位翻转?我要解决的问题是给定一个任意长度的二进制字符串,如何返回字符串的位翻转次数。例如'01101'的位翻转数为3,'1110011'为2等。

我能想出解决这个问题的方法是使用 for 循环和计数器。但是,这似乎太冗长了。有没有办法可以更快地做到这一点?或者python中有一个内置函数可以让我直接这样做吗?感谢您的帮助!

【问题讨论】:

  • 不,不,没有。虽然你可以使用itertools.groupby 来简化你的代码,但至少应该稍微快一点
  • “二进制字符串”是什么意思?您是否有由10 字符 组成的文本,就像按键盘上的1 和0 键一样?还是您正在查看字节级别的原始数据并观察设置和清除位的模式?还是别的什么?
  • @Karl Knechtel 感谢您的评论,我正在寻找类似字符串的输入 :) 刚刚编辑了 OP

标签: python string


【解决方案1】:

不知道内置函数,但这里有一个单行:

bit_flip_count = len([x for x in range(1, len(x0)) if x0[x] != x0[x-1]])

【讨论】:

    【解决方案2】:

    有一种非常快速的方法可以做到这一点,无需任何显式循环并且仅使用 Python 内置函数:您可以将字符串转换为 二进制数 em>,然后使用基于异或的整数技巧检测所有位翻转,然后将整数转换回字符串计数数字位翻转。代码如下:

    # Convert the binary string `s` to an integer: "01101" -> 0b01101
    n = int(s, 2)
    
    # Build a binary mask to skip the most significant bit of n: 0b01101 -> 0b01111
    mask = (1 << (len(s)-1)) - 1
    
    # Check if the ith bit of n is different from the (i+1)th bit of n using a bit-wise XOR:
    # 0b01101 & 0b01111 -> 0b1101  (discard the first bit)
    # 0b01101 >> 1      -> 0b0110
    # 0b1101 ^ 0b0110   -> 0b1011
    bitFlips = (n & mask) ^ (n >> 1)
    
    # Convert the integer back to a string and count the bit flips: 0b1011 -> "0b1011" -> 3
    flipCount = bin(bitFlips).count('1')
    

    这个技巧比其他方法快得多,因为与基于循环的解释代码或处理可迭代的代码相比,整数运算非常优化。以下是我机器上大小为 1000 的字符串的性能结果:

    ljdyer's solution:    96 us     x1.0
    Karl's solution:      39 us     x2.5
    This solution:         4 us    x24.0
    

    如果您使用的是短有界字符串,那么甚至还有 faster ways to count the number of bits set in an integer

    【讨论】:

      【解决方案3】:

      给定一系列值,您可以通过对连续的值进行分组然后对这些组进行计数来找到值更改的次数。将比更改的数量多一个组(因为第一次更改之前的元素也在一个组中)。 (当然,对于一个空序列,这会给你一个 -1 的结果;你可能想单独处理这种情况。)

      Python 中的分组是通过标准库itertools.groupby 内置的。这个工具只考虑连续的组,这通常是一个缺点(例如,如果你想制作一个直方图,你必须先对数据进行排序)但在我们的例子中正是我们想要的。这个工具的整体界面is a bit complex,但是在我们的例子中我们可以简单的使用它:

      from itertools import groupby
      
      def changes_in(sequence):
          return len(list(groupby(sequence))) - 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-05
        • 1970-01-01
        相关资源
        最近更新 更多