字母组合/过滤组合字符串

题目描述

每个数字关联多个字母, 关联关系如下:

  • 0 关联 "a","b","c"
  • 1 关联 "d","e","f"
  • 2 关联 "g","h","i"
  • 3 关联 "j","k","l"
  • 4 关联 "m","n","o"
  • 5 关联 "p","q","r"
  • 6 关联 "s","t"
  • 7 关联 "u","v"
  • 8 关联 "w","x"
  • 9 关联 "y","z"

输入一串数字后, 通过数字和字母的对应关系可以得到多个字母字符串, 要求按照数字的顺序组合字母字符串.

屏蔽字符串: 屏蔽字符串中的所有字母不能同时在输出的字符串出现, 如屏蔽字符串是abc, 则要求字符串中不能同时出现a,b,c, 但是允许同时出现a,b或a,c或b,c等.

给定一个数字字符串和一个屏蔽字符串, 输出所有可能的字符组合.

例如输入数字字符串78和屏蔽字符串ux, 输出结果为uw, vw, vx. 数字字符串78, 可以得到如下字符串uw, ux, vw, vx. 由于ux是屏蔽字符串, 因此排除ux, 最终的输出是uw, vw, vx;

输入描述

第一行输入为一串数字字符串, 数字字符串中的数字不允许重复, 数字字符串的长度大于0, 小于等于5.

第二行输入是屏蔽字符串, 屏蔽字符串的长度一定小于数字字符串的长度, 屏蔽字符串中字符不会重复.

输出描述

输出可能的字符串组合.

注: 字符串之间使用逗号隔开, 最后一个字符串后携带逗号.

示例1

输入:

78
ux

输出:

uw,vw,vx,

示例2

输入:

78
x

输出:

uw,vw,

题解

Python

from itertools import permutations

def main():
    # 读取输入
    # 建立数字到字母的映射关系
    # 就可以得到输入数字所有可能的字符串
    # 然后去掉被屏蔽的字符串, 就得到了结果
    num_str = input()
    assert 0 < len(num_str) < 5
    filter_str = input()

    num_digits = list(map(int, num_str))
    digit_mapping = ["abc", "def", "ghi", "jkl", "mno", "pqr", "st", "uv", "wx", "yz"]
    assert len(digit_mapping) == 10

    # 生成数字到字母的映射
    letters = [digit_mapping[digit] for digit in num_digits]

    def dfs(letters, letter_index, path, result, visited):
        # 如果所有的字母都访问过了, 那就返回
        if letter_index >= len(letters):
            # 将当前路径上的字母加入到结果中
            substr = "".join(path)
            # 过滤字符串
            if filter_str not in substr:
                result.append(substr)
            return
        # 遍历当前索引位置的所有字母
        for char in letters[letter_index]:
            # 如果
            if char not in visited:
                path.append(char)
                visited.add(char)
                # 访问下一个字母组合
                dfs(letters, letter_index + 1, path, result, visited)
                # 将字母从临时路径中移除
                path.pop()
                # 将字母从访问过的记录中移除
                visited.remove(char)

    # 存放最后的结果
    result = []
    # 临时存放经过的路径
    path = []
    # 标记已访问过的字母
    visited = set()
    dfs(letters, 0, path, result, visited)

    # 打印结果
    print(",".join(result), ",", sep="")

if __name__ == "__main__":
    main()