Python:在整数的二进制表示中找到最长的二进制间隙

时间:2018-02-23 15:48:41

标签: python python-3.x

我想知道我的实施是否有效。 我试图使用python找到解决该问题的最简单,最简单的解决方案。

def count_gap(x):
    """
        Perform Find the longest sequence of zeros between ones "gap" in binary representation of an integer

        Parameters
        ----------
        x : int
            input integer value

        Returns
        ----------
        max_gap : int
            the maximum gap length

    """
    try:
        # Convert int to binary
        b = "{0:b}".format(x)
        # Iterate from right to lift 
        # Start detecting gaps after fist "one"
        for i,j in enumerate(b[::-1]):
            if int(j) == 1:
                max_gap = max([len(i) for i in b[::-1][i:].split('1') if i])
                break
    except ValueError:
        print("Oops! no gap found")
        max_gap = 0
    return max_gap

让我知道你的意见。

24 个答案:

答案 0 :(得分:12)

我确实认识到简洁并不意味着可读性和效率。

然而,能够用口语拼出解决方案并立即用Python实现它可以有效地利用我的时间。

对于二进制间隙:嘿,让我们将int转换成二进制,去掉尾随零,分割为' 1'列表,然后在列表中找到最长的元素并获得此元素长度。

def binary_gap(N):
    return len(max(format(N, 'b').strip('0').split('1')))  

答案 1 :(得分:8)

您的实现将整数转换为基数为2的字符串,然后访问字符串中的每个字符。相反,您可以使用<<&访问整数中的每个位。这样做将避免访问每个位两次(首先将其转换为字符串,然后检查它是否是&#34; 1&#34;或者不是在结果字符串中)。它还将避免为字符串分配内存,然后为您检查的每个子字符串分配内存。

您可以通过访问1&lt;&lt;来检查整数的每个位。 0,1 <&lt; 1,...,1&lt;&lt; (x.bit_length)。

例如:

def max_gap(x):
    max_gap_length = 0
    current_gap_length = 0
    for i in range(x.bit_length()):
        if x & (1 << i):
            # Set, any gap is over.
            if current_gap_length > max_gap_length:
                max_gap_length = current_gap_length
            current_gap_length = 0
         else:
            # Not set, the gap widens.
            current_gap_length += 1
    # Gap might end at the end.
    if current_gap_length > max_gap_length:
        max_gap_length = current_gap_length
    return max_gap_length

答案 2 :(得分:2)

正如评论中所建议的那样,itertools.groupby可以有效地对像字符串这样的可迭代元素进行分组。你可以像这样接近它:

from itertools import groupby

def count_gap(x):
    b = "{0:b}".format(x)
    return max(len(list(v)) for k, v in groupby(b.strip("0")) if k == "0")

number = 123456
print(count_gap(number))

首先我们从末端剥离所有零,因为两端的间隙必须是一个。然后itertools.groupby将1和0分组,我们将一个密钥(即&#34; 0&#34;或&#34; 1&#34;)与一个组一起提取(即如果我们将其转换为列表,则为看起来像&#34; 0000&#34;或&#34; 11&#34;)。接下来,如果k为零,我们收集每个组v的长度。从中我们确定了最大的数字,即在那些中最长的零间隙。

答案 3 :(得分:2)

这是我的解决方案:

def solution(N):
    num = binary = format(N, "06b")
    char = str(num)
    find=False
    result, conteur=0, 0

    for c in char:
        if c=='1' and not find:
            find = True
            
        if find and c=='0':
            conteur+=1

        if c=='1':
            if result<conteur:
                result=conteur
            conteur=0

    return result

答案 4 :(得分:1)

这也有效:

def binary_gap(n):
    max_gap = 0
    current_gap = 0

    # Skip the tailing zero(s)
    while n > 0 and n % 2 == 0:
        n //= 2

    while n > 0:
        remainder = n % 2
        if remainder == 0:
            # Inside a gap
            current_gap += 1
        else:
            # Gap ends
            if current_gap != 0:
                max_gap = max(current_gap, max_gap)
                current_gap = 0
        n //= 2

    return max_gap

答案 5 :(得分:1)

使用位移运算符的解决方案 (100%)。基本上复杂度是 O(N)。

def solution(N):
    # write your code in Python 3.6
    meet_one = False
    count = 0
    keep = []
    while N:
        if meet_one and N & 1 == 0:
            count+=1
        
        if  N & 1:
            meet_one = True
            keep.append(count)
            count = 0
        N >>=1

    return max(keep)

答案 6 :(得分:1)

def max_gap(N):
    xs = bin(N)[2:].strip('0').split('1')
    return max([len(x) for x in xs])

说明:

  1. 前导和尾随零在二进制间隙查找中都是多余的 因为它们不受两个1(分别为左和右)的限制
  2. 因此,第1步向左和向右分割零
  3. 然后除以1会产生所有0'z序列
  4. 解决方案:0的子字符串的最大长度

答案 7 :(得分:1)

老问题,但我会使用生成器解决。

from itertools import dropwhile

# a generator that returns binary 
# representation of the input
def getBinary(N):
    while N:
        yield N%2
        N //= 2

def longestGap(N):
    longestGap = 0
    currentGap = 0

    # we want to discard the initial 0's in the binary
    # representation of the input
    for i in dropwhile(lambda x: not x, getBinary(N)):
        if i:
            # a new gap is found. Compare to the maximum
            longestGap = max(currentGap, longestGap)
            currentGap = 0
        else:
            # extend the previous gap or start a new one
            currentGap+=1

    return longestGap

答案 8 :(得分:1)

我认为当输入数字为32(100000)时,可接受的答案无效。这是我的解决方案:

def solution(N):
    res = 0
    st = -1
    for i in range(N.bit_length()):
        if N & (1 << i):
            if st != -1:
                res = max(res, i - st - 1)
            st = i

    return res

答案 9 :(得分:1)

def solution(N):
    # write your code in Python 3.6
    count = 0
    gap_list=[]
    bin_var = format(N,"b")
    for bit in bin_var:
        if (bit =="1"):
            gap_list.append(count)
            count =0
        else:
            count +=1
    return max(gap_list)

答案 10 :(得分:0)

这是另一个有效的解决方案。希望它可以帮助你。你只需要在函数中传递任何数字,它就会返回最长的二进制间隙。

def LongestBinaryGap(num):

n = int(num/2)
bin_arr = []

for i in range(0,n):
    if i == 0:
        n1 = int(num/2)
        bin_arr.append(num%2)
    else:
        bin_arr.append(n1%2)
        n1 = int(n1/2)

        if n1 == 0:
            break

print(bin_arr)
result = ""
count = 0
count_arr = []

for i in bin_arr:
    if result == "found":
        if i == 0:
            count += 1
        else:
            if count > 0:
                count_arr.append(count)
                count = 0
    if i == 1:
        result = 'found'
    else:
        pass

if len(count_arr) == 0:
    return 0
else:
    return max(count_arr)

print(LongestBinaryGap(1130))  # Here you can pass any number.

答案 11 :(得分:0)

这真的很旧,我知道。但这是我的:

def solution(N):
    gap_list = [len(gap) for gap in bin(N)[2:].strip("0").split("1") if gap != ""]
    
    return max(gap_list) if gap_list else 0

答案 12 :(得分:0)

还有一个似乎很容易理解的东西。

def count_gap(x):
     binary_str = list(bin(x)[2:].strip('0'))
     max_gap = 0 
     n = len(binary_str)
     pivot_point = 0

     for i in range(pivot_point, n):
         zeros = 0
         for j in range(i + 1, n):
              if binary_str[j] == '0':
                   zeros += 1 
              else:
                   pivot_point = j
                   break

         max_gap = max(max_gap, zeros)

     return max_gap

答案 13 :(得分:0)

def解决方案(N):

用Python 3.6编写代码

iterable_N = "{0:b}".format(N)
max_gap = 0
gap_positions = []
for index, item in enumerate(iterable_N):
    if item == "1":
        if len(gap_positions) > 0:
           if (index - gap_positions[-1]) > max_gap:
                max_gap = index - gap_positions[-1]
        gap_positions.append(index)
max_gap -= 1 
return max_gap if max_gap >= 0 else 0

答案 14 :(得分:0)

这是一个使用迭代器和生成器的解决方案,它将处理边缘情况,例如,数字32(100000)的二进制间隙为0,0的二进制间隙为0。它不创建列表,而是依靠迭代一次仅一步一步地处理和处理位串的元素,以实现内存高效的解决方案。

def solution(N):
    def counter(n):
        count = 0
        preceeding_one = False
        for x in reversed(bin(n).lstrip('0b')):
            x = int(x)
            if x == 1:
                count = 0
                preceeding_one = True
                yield count
            if preceeding_one and x == 0:
                count += 1
                yield count
        yield count
    return(max(counter(N)))

答案 15 :(得分:0)

def solution(N: int) -> int:
    binary = bin(N)[2:]
    longest_gap = 0
    gap = 0
    for char in binary:
        if char == '0':
            gap += 1
        else:
            if gap > longest_gap:
                longest_gap = gap
            gap = 0
    return longest_gap

答案 16 :(得分:0)

def find(s, ch):
    return [i for i, ltr in enumerate(s) if ltr == ch]

def solution(N):
    get_bin = lambda x: format(x, 'b')
    binary_num = get_bin(N)
    print(binary_num)
    binary_str = str(binary_num)
    list_1s = find(binary_str,'1')
    diffmax = 0
    for i in range(len(list_1s)-1):
        if len(list_1s)<1:
            diffmax = 0
            break
        else:
            diff = list_1s[i+1] - list_1s[i] - 1
            if diff > diffmax:
                diffmax = diff
    return diffmax
    pass

答案 17 :(得分:0)

可以使用strip()和split()函数完成: 步骤:

  1. 转换为二进制文件(删除前两个字符)
  2. 将int转换为字符串
  3. 分别删除尾随的0和1。
  4. 从字符串中拆分为1以查找字符串的子序列
  5. 找到最长子串的长度

第二个strip('1')不是强制性的,但是它将减少要检查的案件并提高时间复杂度 最坏的情况T

def solution(N):
    return len(max(bin(N)[2:].strip('0').strip('1').split('1')))

答案 18 :(得分:0)

def max_gap(N):
    bin = '{0:b}'.format(N)
    binary_gap = []
    bin_list = [bin[i:i+1] for i in range(0, len(bin), 1)] 

    for i in range(len(bin_list)):
        if (bin_list[i] == '1'):
            # print(i)
            # print(bin_list[i])
            # print(binary_gap)
            gap = []
            for j in range(len(bin_list[i+1:])):
                # print(j)
                # print(bin_list[j])
                if(bin_list[i+j+1]=='1'):
                    binary_gap.append(j)
                    # print(j)
                    # print(bin_list[j])
                    # print(binary_gap)
                    break
                elif(bin_list[i+j+1]=='0'):
                    # print(i+j+1)
                    # print(bin_list[j])
                    # print(binary_gap)
                    continue
                else:
                    # print(i+j+1)
                    # print(bin_list[i+j])
                    # print(binary_gap)
                    break
        else:
            # print(i)
            # print(bin_list[i])
            # print(binary_gap)
            binary_gap.append(0)


    return max(binary_gap)
    pass

答案 19 :(得分:0)

这有效

def solution(number):
    # convert number to binary then strip trailing zeroes
    binary = ("{0:b}".format(number)).strip("0")
    longest_gap = 0
    current_gap = 0
    for c in binary:
        if c is "0":
           current_gap = current_gap + 1
        else:
           current_gap = 0

        if current_gap > longest_gap:
           longest_gap = current_gap 


    return longest_gap

答案 20 :(得分:0)

sorted

答案 21 :(得分:0)

这也有效:

def solution(N):
    bin_num = str(bin(N)[2:])
    list1 = bin_num.split('1')
    max_gap =0
    if bin_num.endswith('0'):
        len1 = len(list1) - 1
    else:
        len1 = len(list1)
    if len1 != 0:
        for i in range(len1):
            if max_gap < len(list1[i]):
                max_gap = len(list1[i])
    return max_gap

答案 22 :(得分:-1)

def solution(N):
    # Convert the number to bin 
    br = bin(N).split('b')[1]
    sunya=[]
    groupvalues=[]
    for i in br:
        count = i
        if int(count) == 1:
            groupvalues.append(len(sunya))
            sunya=[]
        if int(count) == 0:
            sunya.append('count') 

    return max(groupvalues)

答案 23 :(得分:-1)

def solution(N):
bin_num = str(bin(N)[2:])
bin_num = bin_num.rstrip('0')
bin_num = bin_num.lstrip('0')
list1 = bin_num.split('1')
max_gap = 0

for i in range(len(list1)):
    if len(list1[i]) > max_gap:
        max_gap = len(list1[i])

return (max_gap)