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