用python实现密码变换 | 豆包MarsCode AI刷题

56 阅读5分钟

题目:

设计了一套密码变换规则,将输入的字符串转换成一串数字密码。变换规则如下:

  1. 小写字母按以下映射关系进行转换:
  • a, b, c -> 2
  • d, e, f -> 3
  • g, h, i -> 4
  • j, k, l -> 5
  • m, n, o -> 6
  • p, q, r, s -> 7
  • t, u, v -> 8
  • w, x, y, z -> 9
  1. 大写字母先转为小写字母,再跳到字母表中的前一个字母,并按上述规则转换为对应的数字。例如,B 转换为 a,再转换为 2A 特殊处理,先变为 Z,再转换为 9
  2. 非字母字符保持不变。 例如:对于输入字符串 "LIming0701",转换后的数字密码为 5464640701

对题目进行解释说明:

题目要求设计一个密码变换规则,将输入的字符串(可能包含小写字母、大写字母和非字母字符)转换成一串数字密码。转换规则如下:

  1. 小写字母的转换

    • 小写字母 'a', 'b', 'c' 都映射为数字 '2'。
    • 小写字母 'd', 'e', 'f' 都映射为数字 '3'。
    • 以此类推,直到小写字母 'w', 'x', 'y', 'z' 都映射为数字 '9'。
  2. 大写字母的转换

    • 大写字母首先转换为对应的小写字母,然后跳到字母表中的前一个字母('A' 除外)。
    • 例如,大写字母 'B' 转换为小写字母 'b',然后 'b' 跳到字母表中的前一个字母 'a',最后映射为数字 '2'。
    • 大写字母 'A' 是一个特殊情况,它先被视为 'Z',然后映射为数字 '9'。
  3. 非字母字符的转换

    • 非字母字符(如数字、标点符号、空格等)保持不变,直接作为数字密码的一部分。

举个例子,对于输入字符串 "LIming0701":

  • 'L' 是大写字母,转换为小写 'l',然后跳到前一个字母 'k',映射为数字 '5'。
  • 'I' 是大写字母,转换为小写 'i',然后跳到前一个字母 'h',映射为数字 '4'。
  • 'm', 'i', 'n', 'g' 是小写字母,分别映射为数字 '6', '4', '6', '4'。
  • '0701' 是非字母字符,保持不变。

因此,转换后的数字密码为 "5464640701"。

题目要求用python实现一个函数 solution(s: str) -> str,该函数接受一个字符串 s 作为输入,并返回根据上述规则转换后的数字密码作为输出。实现这个函数需要正确地处理每种字符类型(小写字母、大写字母和非字母字符),并按照题目要求将它们转换为相应的数字或保持不变。

下面是用python写的代码

def solution(s: str) -> str:
    # write code here
    char_to_digit = {
        'a': '2', 'b': '2', 'c': '2',
        'd': '3', 'e': '3', 'f': '3',
        'g': '4', 'h': '4', 'i': '4',
        'j': '5', 'k': '5', 'l': '5',
        'm': '6', 'n': '6', 'o': '6',
        'p': '7', 'q': '7', 'r': '7', 's': '7',
        't': '8', 'u': '8', 'v': '8',
        'w': '9', 'x': '9', 'y': '9', 'z': '9'
    }
    
    result = []

    for char in s:
        if char.islower():  # 小写字母直接转换
            result.append(char_to_digit[char])
        elif char.isupper():  # 大写字母转换
            if char == 'A':
                result.append('9')  # 特殊处理 A -> Z -> 9
            else:
                # 转换为小写字母并跳到前一个字母
                lower_char = chr(ord(char.lower()) - 1)
                result.append(char_to_digit[lower_char])
        else:  # 非字母字符保持不变
            result.append(char)

    return ''.join(result)

if __name__ == '__main__':
    print(solution(s="LIming0701") == '5464640701')
    print(solution(s="PassW0rd") == '62778073')
    print(solution(s="helloWORLD123") == '4355686752123')

步骤解释:

  1. 定义映射关系

    • 首先,创建一个字典 char_to_digit,用于存储小写字母到数字的映射关系。这个字典根据题目要求,将每个小写字母映射到对应的数字上。
  2. 初始化结果列表

    • 创建一个空列表 result,用于存储转换后的数字密码。列表比字符串更适合在这个场景中使用,因为我们可以逐个字符地添加元素,最后再将列表转换为字符串。
  3. 遍历输入字符串

    • 使用一个循环遍历输入字符串 s 中的每个字符。
  4. 字符分类处理

    • 小写字母:如果字符是小写字母,直接通过字典 char_to_digit 查找并添加到结果列表中。
    • 大写字母:如果字符是大写字母,首先判断是否是 'A'。如果是 'A',则特殊处理为 '9'(因为 'A' 转换为 'Z' 再转换为 '9')。对于其他大写字母,先将其转换为小写字母,然后利用 ASCII 码减去 1 来得到字母表中的前一个字母(注意,这里不需要担心 'A' 的情况,因为已经在前面单独处理了)。接着,通过字典 char_to_digit 查找并添加到结果列表中。
    • 非字母字符:如果字符既不是小写字母也不是大写字母,则保持不变,直接添加到结果列表中。
  5. 返回结果

    • 最后,使用 ''.join(result) 将结果列表转换为字符串,并返回这个字符串作为最终的数字密码。

这个思路的关键在于正确地分类处理每个字符,并根据题目要求进行相应的转换。通过使用字典来存储映射关系,可以高效地查找每个小写字母对应的数字。同时,通过 ASCII 码操作来处理大写字母的转换,也是一种简洁有效的方法。整个算法的时间复杂度是线性的,即 O(n),其中 n 是输入字符串的长度,因为每个字符都只被处理一次。