Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 二进制表示中连续数的最大长度_Python_Algorithm_Binary - Fatal编程技术网

Python 二进制表示中连续数的最大长度

Python 二进制表示中连续数的最大长度,python,algorithm,binary,Python,Algorithm,Binary,试图在包含负数的二进制表示中找到1的最大长度。在以下代码中,输入文件是一个文本文件,其中: 第一行是带有样本整数的多行 从第二行开始的每一行只有一个样本整数 示例文件: 4-样本数量 3-样本 0- 1- 2- 结果:2 任务:打印输入文件中所有样本整数中找到的最大整数数。找到需要O(n)时间且只需一次通过所有样本的解决方案 如何修改解决方案以处理任意的负整数(或至少针对n≤ 10000)尺寸 更新: 据我所知,负数的二进制表示是基于二的补码(“s_补码”)。例如: n = 123 f"{(

试图在包含负数的二进制表示中找到1的最大长度。在以下代码中,输入文件是一个文本文件,其中:

  • 第一行是带有样本整数的多行
  • 从第二行开始的每一行只有一个样本整数
示例文件:

4-样本数量

3-样本

0-

1-

2-

结果:2

任务:打印输入文件中所有样本整数中找到的最大整数数。找到需要O(n)时间且只需一次通过所有样本的解决方案

如何修改解决方案以处理任意的负整数(或至少针对
n≤ 10000
)尺寸

更新:

据我所知,负数的二进制表示是基于二的补码(“s_补码”)。例如:

n = 123
f"{(1<<32)+n:032b}"[-32:]  --> '00000000000000000000000001111011'

n = -123
f"{(1<<32)+n:032b}"[-32:]  --> '11111111111111111111111110000101'
+3->011

-3->101

在一般情况下,如何将整数转换为二进制字符串表示,并考虑其符号

def maxConsecutive(input): 
    return max(map(len,input.split('0'))) 

def max_len(input_file):
    max_len = 0
    with open(input_file) as file:
        first_line = file.readline()
        if not first_line:
            return 0
        k = int(first_line.strip()) # number of tests
        for i in range(k):
            line = file.readline().strip()
            n = int(line)
            xs = "{0:b}".format(n)
            n = maxConsecutive(xs)
            if n > max_len:
                max_len = n
    return max_len

print(max_len('input.txt'))
更新2: 这是Yandex竞赛培训页面的第二项任务:

您需要在那里注册以测试您的解决方案

到目前为止,这里给出的所有解决方案都在测试9中失败

更新3:Haskell中通过所有Yandex测试的解决方案

import Control.Monad (replicateM)

onesCount :: [Char] -> Int
onesCount xs = onesCount' xs 0 0
    where
        onesCount' "" max curr 
            | max > curr = max 
            | otherwise  = curr
        onesCount' (x:xs) max curr
            | x == '1' = onesCount' xs max $ curr + 1 
            | curr > max = onesCount' xs curr 0 
            | otherwise = onesCount' xs max 0

getUserInputs :: IO [Char]
getUserInputs = do
    n <- read <$> getLine :: IO Int
    replicateM n $ head <$> getLine

main :: IO ()
main = do
    xs <- getUserInputs 
    print $ onesCount xs
import Control.Monad(复制项)
OneScont::[Char]->Int
OneScont xs=OneScont的xs 0
哪里
OneScont的“最大电流”
|最大值>当前值=最大值
|否则=货币
OneScont'(x:xs)最大电流
|x=='1'=OneScont'xs最大$curr+1
|curr>max=onescont'xscurr 0
|否则=OneScont的xs最大值为0
getUserInputs::IO[Char]
getUserInputs=do

n假设

OP需要2的二进制补码

Python的整数已经使用了2的补码,但是由于 任意精度,负数的二进制表示 在开始时会有一个无限长的1字符串,很像正数 数字有一个无限的0字符串。因为这显然是不可能的 如图所示,它用减号表示。

这导致:

>>> bin(-5)
'-0b101'
所以为了消除无限精度的影响,我们可以显示2对固定位数的补码。这里使用16,因为OP提到的数字小于10000

>>> bin(-5 % (1<<16))            # Modulo 2^16
>> bin(-5 & 0b1111111111111111)  # 16-bit mask
'0b1111111111111011'
测试输出

代码

def maxConsecutive(input):
    return max(map(len,input[2:].split('0')))  # Skip 0b at beginning of each

def max_len(input_file):
    max_len_ = 0
    with open(input_file) as file:
        first_line = file.readline()
        if not first_line:
            return 0
        k = int(first_line.strip()) # number of tests
        for i in range(k):
            line = file.readline().strip()
            n = int(line)
            xs = bin(n & '0b1111111111111011') # number in 16-bit 2's complement
            n = maxConsecutive(xs)
            if n > max_len_:
                max_len_ = n
    return max_len_
max_-len的代码简化

最大长度可以减少到:

def max_len(input_file):
  with open(input_file) as file:
    return max(maxConsecutive(bin(int(next(file).strip()), 0b1111111111111011)) for _ in range(int(next(file))))

对于负数,您必须决定字长(32位、64位……),或将其作为绝对值处理(即忽略符号),或为每个值使用最小位数

控制字长的一种简单方法是使用格式字符串。通过将值与所选字大小对应的幂2相加,可以获得负位。这将为正数和负数提供适当的位

例如:

n = 123
f"{(1<<32)+n:032b}"[-32:]  --> '00000000000000000000000001111011'

n = -123
f"{(1<<32)+n:032b}"[-32:]  --> '11111111111111111111111110000101'
n=123

f“{(1Thanks!但是您的解决方案没有考虑负数的2的补码。请参阅我的问题更新。@dokondr是的。请参阅我的更新答案,并举例说明。通过检查输入[0]是否为符号,即“-”,来工作。如果是,则使用输入[1::]跳过。MaxConcertive(+3)应返回2,MaxConcertive(-3)应该回来1@dokondr--对于line=
'+3'
,n=3。然后我们有xs=“{0:b}”。format(n)将n转换为一个基数为2的字符串。这将导致
11
。因此我们调用
maxconcertive('11')
,得到2。对于
line=
'-3'`,n=-3,xs=-11
。我们调用
maxconcertive('-11'))`也可以得到2。二的补码是对二进制数的数学运算……它作为一种有符号数表示方法用于计算。N位数的二的补码定义为其相对于2^N的补码。例如,对于三位数010,二的补码是110,因为010+110=1000。二的s补码是通过数字的倒数加1计算出来的。2的补码是计算机上表示有符号整数最常用的方法。对于-3的补码是101。因此MaxContinuous必须为-3返回101,对于其他负数的补码是101。谢谢,我很难理解
“{(1
“{0:0{1}b}”格式((1谢谢!不幸的是,此解决方案和另一个解决方案没有通过所有测试。请参阅更新2。能否在帖子中包含测试数据和预期结果,我无法登录到链接站点。在此站点上,他们在一系列测试中运行您的代码。您所能看到的只是通过的测试编号和失败的测试编号的列表。它们不显示测试数据,因此您只能猜测错误并重试。对于每个问题,您有100次尝试。在登录链接中,我给您提供了一个注册Yandex竞赛的选项。不幸的是,没有其他方法可以注册。请参阅我在Haskell中的更新3,其中包含通过所有Yandex测试的解决方案。我不太熟悉Haskell的说谎者,但函数似乎期望每一行都已表示为1和0的字符串。OneScont的签名接受一个字符数组(即字符串),并返回一个最大连续“1”的数字字符串中的字符。我看不出整数值在该代码中转换为其位表示形式的位置。它似乎只做了
max(map(len,bits.split(“0”))
谢谢,我会检查!
n = 123
f"{(1<<32)+n:032b}"[-32:]  --> '00000000000000000000000001111011'

n = -123
f"{(1<<32)+n:032b}"[-32:]  --> '11111111111111111111111110000101'
n        = -123
wordSize = len(f"{abs(n):b}")+1
bits     = f"{(1<<wordSize)+n:0{wordSize}b}"[-wordSize:]
maxOnes  = max(map(len,bits.split("0")))

print(maxOnes) # 1   ('10000101')