Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.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 基于ID列表高效计算XOR(^)校验和的方法_Python_Checksum_Xor - Fatal编程技术网

Python 基于ID列表高效计算XOR(^)校验和的方法

Python 基于ID列表高效计算XOR(^)校验和的方法,python,checksum,xor,Python,Checksum,Xor,当我在谷歌上搜索关于Python列表理解的信息时,有人向我提供了一个谷歌foobar挑战,在过去几天里,我一直在慢慢地寻找乐趣。最新挑战: 有效地调用生成ID列表,忽略每一行中不断增加的ID数,直到剩下一个ID为止。然后,您应该对ID进行异或(^)以生成校验和。我创建了一个输出正确答案的工作程序,但是它的效率不足以在分配的时间内通过所有测试用例(通过6/10)。50000的长度应该在20秒内产生结果,但需要320秒 有人能把我引向正确的方向吗,但是请不要为我做这件事,我很高兴在这个挑战中激励自

当我在谷歌上搜索关于Python列表理解的信息时,有人向我提供了一个谷歌foobar挑战,在过去几天里,我一直在慢慢地寻找乐趣。最新挑战:

有效地调用生成ID列表,忽略每一行中不断增加的ID数,直到剩下一个ID为止。然后,您应该对ID进行异或(^)以生成校验和。我创建了一个输出正确答案的工作程序,但是它的效率不足以在分配的时间内通过所有测试用例(通过6/10)。50000的长度应该在20秒内产生结果,但需要320秒

有人能把我引向正确的方向吗,但是请不要为我做这件事,我很高兴在这个挑战中激励自己。也许有一个数据结构或算法我可以实现,以加快计算时间

代码背后的逻辑:

  • 首先,输入起始ID和长度

  • 将生成一个ID列表,忽略每一新行中越来越多的ID,从忽略第一行中的0开始

  • 使用for循环对id列表中的所有数字进行异或

  • 答案以int形式返回



  • 无论是
    templast
    还是
    answerlist
    都不是真正需要的。让我们在你的代码中进行几次测试,看看如何消除它们。< /P>
  • 首先,让我们将
    templast
    的初始化设置为一行程序。这:

    templist = []
    for y in range (x,x + length):
        templist.append(y)
    
    变成这样:

    templist = list(range(x, x + length))
    
    answerlist.extend(templist[:lengthmodified])
    
  • 然后让我们对
    应答列表
    执行相同的操作。这:

    for d in range (0,lengthmodified):
        answerlist.append(templist[d])
    
    变成这样:

    templist = list(range(x, x + length))
    
    answerlist.extend(templist[:lengthmodified])
    
  • 现在让我们来看看它们后来是如何使用的。如果我们现在忽略
    lengthmodified-=1
    x+=length
    ,我们有:

    templist = list(range(x, x + length))
    answerlist.extend(templist[:lengthmodified])
    
    for n in answerlist:
        prestringresult ^= n
    
    answerlist = []
    
    与其扩展
    answerlist
    ,迭代它,然后清除它,不如只迭代
    templast

    templist = list(range(x, x + length))
    
    for n in templist[:lengthmodified]:
        prestringresult ^= n
    
    现在也不需要
    圣殿骑士
    ,所以让我们也跳过构建它

    for n in range(x, x + lengthmodified):
        prestringresult ^= n
    
    templast
    answerlist
    不见了

    这里唯一缺少的部分是工作
    answerlist.append(int(stringresult))
    返回。我会留给你去弄清楚的

    总的来说,这里的教训是尽可能避免显式的
    for
    循环。为遍历容器的
    循环编写大量的
    ,这是一种C思维方式。在Python中,通常有多种方法可以一次彻底检查集合。这样做可以利用该语言快速的内置操作


    另外,惯用Python也很容易阅读。

    您可能需要一种不同的方法,而不仅仅是像John那样的小改进。我刚刚写了一个解决方案,可以在我的电脑上在大约2秒钟内完成
    回答(0,50000)
    。我仍然一行一行地做,但不是对行范围内的所有数字进行XOR运算,而是一点一点地做。行中设置了多少个1位数字?[*]奇数数字?然后我翻转我答案的1位。对于2位、4位、8位等,直到230位,也是如此。因此,对于每一行,它只是31个小计算(而不是实际上对数万个数字进行XOR运算)

    [*]可以在恒定时间内快速计算,仅从范围的开始/停止

    编辑:既然您要求提供另一个提示,下面介绍如何计算在某个范围(a、b)内设置1位的频率。计算它设置在范围(0,a)内的频率,并从设置在范围(0,b)内的频率中减去该频率。如果范围从零开始,则更容易。在某个范围(0,c)内,1位设置的频率是多少?简单:
    c//2次。那么,在某个范围(a,b)中,1位设置的频率是多少?只需
    b//2-a//2次。较高的位是相似的,只是稍微复杂一点


    编辑2:哦,等等,我刚想起来。。。有一种简单的方法可以计算某个范围(a,b)内所有数字的异或。再次将工作划分为工作范围(0,a)和范围(0,b)。某些范围(0,c)内的所有数字的异或很容易,因为有一个很好的模式(如果对从0到30的所有c进行异或,您将看到它)。使用这个,我现在在大约0.04秒的时间内解出
    答案(0,50000)

    ,我在不使用列表的情况下得到了一点改进,但它仍然会在大数目的情况下失败。嵌套循环会降低速度。我认为你需要遵循波希曼的逻辑,因为暴力很少是解决这类问题的方法


    在这个问题上,大多数人都会被超过时间限制。是的! 这个问题可以这样得出结论:“在恒定时间内,找出位于一定范围内的所有数字的异或。”是的,恒定时间

    所以从3-6开始,答案应该是O(1)时间内的3^4^5^6=4

    解决方案: XOR在本质上是关联的。所以A^B^C可以写成B^A^C。 此外,我们知道XOR的意思是:“AND”将相同的位转换为True,即1,将不同的位转换为2

    根据这两种性质,我们可以写: 3-6中所有数字之间的异或可以写成:

    3^4^5^6 = (0^1^2)^(0^1^2) ^ (3^4^5^6)
            = (0^1^2^3^4^5^6) ^ (0^1^2) (this comes from the associative nature of xor)
            = XOR betn all the numbers from (0-6) ^ XOR betn all the numbers from (0-2)...eq(1)
    
    现在,如果我们能在一个恒定的时间内找到从0到某个整数的所有数字的异或,我们就会得到答案

    幸运的是,我们有一种模式:

    请参见以下示例:

    (0-1): 0 ^ 1 = 1 (1)
    (0-2): 0 ^ 1 ^ 2 = 3 (2+1)
    (0-3): 0 ^ 1 ^ 2 ^ 3 = 0 (0)
    (0-4): 0 ^ 1 ^ 2 ^ 3 ^ 4 = 4 (4)
    
    (0-5): 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 = 1 (1)
    (0-6): 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 = 7 (6+1)
    (0-7): 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^  7 = 0 (0)
    (0-8): 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8 = 8 (8)
    
    
    So the pattern for finding the xor between all the integers between 0 to n is:
    if n%4 == 1 then, answer = 1
    if n%4 == 2 then, answer = n+1
    if n%4 == 3 then, answer = 0
    if n%4 == 0 then answer = n 
    
    Therefore, XOR(0-6) becomes 7 (since 6%4 ==2) and XOR(0-2) becomes 3 (since 2%4 ==2)
    
    Therefore, the eq(1) now becomes:
    3^4^5^6 = 7 ^ 3 = 4
    
    现在问题很简单,我们大多数人都会因为超过时间限制的错误而陷入困境,因为我们试图在每个循环中进行异或运算,如果输入/迭代的数量增加,这将是巨大的。 下面是我用python编写的工作解决方案,所有测试用例都通过了google的测试:

    #Main Program
    def answer(start, length):
        checkSum = 0
        for l in range(length, 0, -1):
            checkSum = checkSum ^ (getXor(start + l-1) ^ getXor(start-1))
            start = start + length
        return checkSum
    
    def getXor(x):
        result = [x, 1, x+1, 0]
        return result[x % 4]
    

    你有两个内环。试着摆脱它们。这能让它快多少?你是对的。我修剪了John提到的脂肪,在运行时大大减少了脂肪,但仍然不够好。您的解决方案听起来非常有趣,1.52运行时听起来很棒。但是,我不熟悉xoring“位”的过程