Я хотел бы знать, эффективна ли моя реализация. Я попытался найти самое простое и простое решение этой проблемы с помощью 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

Дайте мне знать ваше мнение.

10
user8358337 23 Фев 2018 в 18:48

15 ответов

Лучший ответ

Ваша реализация преобразует целое число в строку с двумя базовыми значениями, а затем посещает каждый символ в строке. Вместо этого вы можете просто посетить каждый бит в целом числе, используя << и &. Это позволит избежать посещения каждого бита дважды (сначала преобразовать его в строку, а затем проверить, является ли он «1» или нет в результирующей строке). Это также позволит избежать выделения памяти для строки, а затем для каждой проверяемой подстроки.

Вы можете проверить каждый бит целого числа, посетив 1 << 0, 1 << 1, ..., 1 << (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
11
Jean-Paul Calderone 23 Фев 2018 в 17:43
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
0
pzaenger 19 Янв 2020 в 12:17
def solution(number):

    bits = [int(digit) for digit in bin(number)[2:]]
    occurences = [i for i, bit in enumerate(bits) if(bit==1)]
    res = [occurences[counter+1]-a-1 for counter, a in enumerate(occurences) if(counter+1 < len(occurences))]

    if(not res):
        print("Gap: 0")
    else:
        print("Gap: ", max(res))

number = 1042
solution(number)
0
PythonNoob 5 Мар 2019 в 17:39
def max_gap(N):
    xs = bin(N)[2:].strip('0').split('1')
    return max([len(x) for x in xs])

Объяснение :

  1. И начальные, и конечные нули являются избыточными с обнаружением двоичного разрыва, поскольку они не ограничены двумя единицами (слева и справа соответственно)
  2. Итак, шаг 1 чередование нулей влево и вправо
  3. Тогда разбиение на 1 дает все последовательности 0'z
  4. Решение: максимальная длина подстроки 0
3
Orenico 29 Окт 2018 в 11:15

Как указано в комментариях, 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 группирует единицы и нули, и мы извлекаем ключ (т. Е. «0» или «1») вместе с группой (т. Е. Если мы преобразуем его в список, он выглядит как «0000» или «11») , Далее мы собираем длину для каждой группы v, если k равно нулю. И из этого мы определяем наибольшее число, то есть самый длинный разрыв нулей среди этих.

2
Mr. T 23 Фев 2018 в 16:13

Я понимаю, что краткость не означает удобочитаемость и эффективность.

Тем не менее, способность изложить решение на разговорном языке и реализовать его на Python в кратчайшие сроки представляет собой эффективное использование моего времени.

Для двоичного разрыва: эй, давайте преобразовать int в двоичный файл, убрать завершающие нули, разделить на «1» в списке, затем найти самый длинный элемент в списке и получить длину этого элемента.

def binary_gap(N):
    return len(max(format(N, 'b').strip('0').split('1')))  
23
Aivar Paalberg 2 Апр 2018 в 12:27

Старый вопрос, но я бы решил его с помощью генераторов.

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
1
SMir 12 Ноя 2018 в 01:59

Это также работает:

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
0
kritika 5 Окт 2018 в 07:30

Это также работает:

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
1
Hooman Tamimi 1 Апр 2018 в 13:19

Это работает

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
0
DannyMbaluka 8 Июл 2019 в 18:26
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
0
Dhritiman Das 13 Сен 2019 в 09:38

Это можно сделать с помощью функций strip () и split (): Шаги:

  1. Преобразовать в двоичный файл (удалить первые два символа)
  2. Конвертировать int в строку
  3. Удалить трейлинг и начиная 0 и 1 соответственно
  4. Разделите на 1 из строки, чтобы найти подпоследовательности строк
  5. Найдите длину самой длинной подстроки

Второй strip('1') не обязателен, но он уменьшит количество проверяемых случаев и улучшит временную сложность Худший случай Т

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

1
Harsh Shah 10 Дек 2019 в 23:25
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)
-1
Kushal Kadam 9 Окт 2018 в 03:47
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
0
m.joy 2 Фев 2020 в 13:28

Я думаю, что принятый ответ не работает, когда введено число 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
2
Jingda Mai 16 Ноя 2018 в 13:28