首页 > 解决方案 > 碰撞计数器:每次在 2 个列表中的同一位置有相同的字符时加 1?

问题描述

我正在尝试在 python 中创建一个碰撞计数器,每次在两个列表中的同一位置存在相同字符时都会计数。我这样做是为了尝试确定 Vigenère 密文中使用的密钥长度。

例如,我有一个 cipher text c = "aabaab",我已将其转换为一个列表。我将字符移动 1 个位置c_shift = "baabaa",现在我计算“碰撞”的数量,也就是相同位置中的相同字符。在此示例中,有 2 个碰撞,一个在位置 1,另一个在位置 4。

在我的真实代码中,我有一个更大的密文,并且想要将密文移动 26 次,并获得每次移动的冲突计数。我的班次代码有效,但计数冲突部分无效。最后,我希望它打印出班次(1 - 26)和该班次的碰撞总数。

我尝试了多个堆栈溢出教程,但收效甚微。我尝试使用zip,但输入时出现错误[collisions += 1 for k, l in zip(c, c_shift) if k == l]。我也试过set(c).intersection(c_shift),但我不知道如何将它与柜台联系起来。

c = list(c) #converts cipher text to list
# creates list variable c_shift equal to cipher text c
c_shift = c
for j in range(1, 26): # I want to shift cipher text 26 times
    collisions = 0
    # remove last character from ciphertext
    last: str = c_shift.pop()

    # add last character to front of ciphertext (shifting by 1 every 
    # time for loop iterates)
    c_shift.insert(0, last)

    #this is where my code stops functioning correctly. 

    for k, l in zip(c, c_shift):
        if k == l:
            collisions += 1
    print(j, " ", collisions)

我想要一个显示移位和总碰撞次数的输出。

例如:[1 , 7], [2, 36], [3, 97], [4, 10]...

其中第一个数字1,2,3,4,...是班次 1-26,下一个数字是每个班次的最大碰撞次数。

标签: pythonpython-3.x

解决方案


c = list(c)
c_shift = c

这是问题的核心。您正在创建一个列表,然后将其存储在 中c,然后将对该列表的引用存储在c_shift. 对引用的任何更改c_shift也会影响c.

您要创建两个不同的列表:

c, c_shift = list(c), list(c)

这将创建两个列表对象,您所做的任何更改c_shift也不会更改c


推荐阅读