检查相邻键盘字符的字符串

Checking a string for adjacent keyboard characters

我正在尝试查看字符串中的字符在键盘上是否相邻。

此代码将键盘初始化为 3d 数组 "Array3":

KeyboardRow1 = ["`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", ""]
KeyboardRow2 = ["", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", ""] 
KeyboardRow3 = ["", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "", "", ""] 
KeyboardRow4 = ["", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "", "", ""]
KeyboardRow1S = ["~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", ""]
KeyboardRow2S = ["", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "{", "}", "|"]
KeyboardRow3S = ["","A", "S", "D", "F", "G", "H", "J", "K", "L", ":", "", "", ""] 
KeyboardRow4S = ["", "Z", "X", "C", "V", "B", "N", "M", "<", ">", "?", "", "", ""]
Array2R = [KeyboardRow1, KeyboardRow2, KeyboardRow3, KeyboardRow4]
Array2S = [KeyboardRow1S, KeyboardRow2S, KeyboardRow3S, KeyboardRow4S]
Array3 = [Array2R, Array2S]

此代码将输入密码的每个字符转换为它在数组中的坐标,并将这些坐标存储在 KeyboardPositions 中。

KeyboardPositions = []
for z in range(0,PasswordLength):
    for i in range(2):
        for j in range(4):
            for k in range (14):
                if Password[z] == str(Array3[i][j][k]):
                    KeyboardPositions.append((i,j,k))

我遇到问题的这段代码检查邻接关系。

  for x in range(PasswordLength-1):
        for y in range(3):
            if KeyboardPositions[x][y] == (KeyboardPositions[x+1][y]-1) or KeyboardPositions[x][y] == (KeyboardPositions[x+1][y]+1):
                Adjacency = Adjacency + 1

print("There are " + str(Adjacency) + " adjacent characters")

最后一段代码试图做的是查看行、列或移位(如果保持移位,则为 1 或 0)坐标是否彼此为 +- 1。但是,它会将 "t" 和 "a" 之类的东西算作相邻的,因为它们仅相隔 1 行。我怎样才能解决这个问题 ?谢谢

你为什么不给键盘上的每个字符分配一个数字,然后通过减去它们来检查它们是否相邻?像这样:
首先定义一个字典来存储数字:

n = {}

n['q'] = 1
n['w'] = 2
n['e'] = 3
... n['p'] = 10

而第二行,从20开始数,避免ap成为邻居:

n['a'] = 20
n['s'] = 21
... n['l'] = 28

那么,你可以使用这个功能:

def check_neighbourhood(a,b):
    return n[a] == n[b] or abs(n[a] - n[b]) == 1 or abs(n[a] - n[b]) == 19

n[a] - n[q] = 19,所以我们应该处理这个。

我会这样做(假设代码中存在 KeyboardRowN):

from itertools import combinations

Rows = [KeyboardRow1, KeyboardRow2, KeyboardRow3, KeyboardRow4, \
        KeyboardRow1S, KeyboardRow2S, KeyboardRow3S, KeyboardRow4S]

row_len = len(KeyboardRow1)

def pass2index(passwd):
    """Produce a list of pairs (coordinates) for each character of a given passphrase. 
    Each pair encodes row and column in a list of keyboard keys."""
    coordinates = []
    for c in passwd:
        for i, r in enumerate(Rows):
            # check if password's char is in the current row
            try:
                # modulo 4 used for shifted keys,
                # so that 'k' and 'K' have the same row index
                coordinates.append((i % 4, r.index(c)))
            except:
                pass
    return coordinates

def adjacency(coords):
    """Produce a number of adjacency for a list of coordinates."""
    adjacent = 0
    # produce combinations of coordinates to compare each two letters
    # i.e. combinations of two coordinates
    for pairs in combinations(coords, 2):
        # two coordinates are adjacent if their rows and columns
        # differ by +/- 1
        if (abs(pairs[0][0] - pairs[1][0]) < 2) \
           and (abs(pairs[0][1] - pairs[1][1]) < 2):
            # print(pairs) # used for examples below
            adjacent += 1
    return adjacent

代码注释很好,希望您不需要额外的解释。

你可以按如下方式查看(我把print(pairs)注释掉了,这样你就明白为什么会得到这些结果了):

>>> adjacency(pass2index('jko'))
((2, 7), (2, 8))
((2, 8), (1, 9))
2
>>> adjacency(pass2index('aqzsp'))
((2, 1), (1, 1))
((2, 1), (3, 1))
((2, 1), (2, 2))
((1, 1), (2, 2))
((3, 1), (2, 2))
5
>>> adjacency(pass2index('Kl'))
((2, 8), (2, 9))
1
>>> adjacency(pass2index('7Yu'))
((0, 7), (1, 6))
((0, 7), (1, 7))
((1, 6), (1, 7))
3