×

C++ Java python

(A卷,100分)- 字母组合(Java & JS & Python & C)

陈己墨 陈己墨 发表于2024-07-17 10:15:31 浏览343 评论0

抢沙发发表评论

(A卷,100分)- 字母组合(Java & JS & Python & C)

题目描述

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

  • 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;

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


输出描述

输出可能的字符串组合

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


用例

输入78
ux
输出uw,vw,vx,
说明
输入

78
x

输出uw,vw,
说明

题目解析

本题由两块逻辑组成:

1、根据提供的数字字符串,得到字母组合字符串。这块其实就是求组合问题,可以使用回溯算法,逻辑可以参考:LeetCode - 17 电话号码的字母组合_伏城之外的博客-CSDN博客

2、排除包含屏蔽字符串的字母组合字符串,而本题中判断一个字符串是否包含另一个字符串的逻辑是:屏蔽字符串中的所有字母不能同时在输出的字符串中出现

数字字符串中的数字不允许重复

屏蔽字符串中字符不会重复



JS算法源码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  const nums = await readline();
  const filter = await readline();

  const map = [
    "abc",
    "def",
    "ghi",
    "jkl",
    "mno",
    "pqr",
    "st",
    "uv",
    "wx",
    "yz",
  ];

  const result = [];

  /**
   * 回溯算法求组合
   * @param {*} level 组合的层级
   * @param {*} path 记录组合字符串
   */
  function dfs(level, path) {
    // 组合层数到达要求时,当前组合字符串完成
    if (level == nums.length) {
      const set = new Set(path);

      for (let c of filter) {
        if (!set.has(c)) {
          result.push(path.join(""));
          return;
        }
      }

      return;
    }

    // 当前层级的数字
    const num = nums[level] - "0";
    // 该数字关联的多个字母
    const letters = map[num];

    // 遍历当前层级可选的字母
    for (let i = 0; i < letters.length; i++) {
      // 选择字母加入当前组合
      const letter = letters[i];

      path.push(letter);
      // 继续组合下一个层级的字母选择
      dfs(level + 1, path);
      path.pop();
    }
  }

  // 回溯算法求组合
  dfs(0, [], result);

  // 拼接结果字符串
  console.log(result.join(",") + ",");
})();


Java算法源码

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
  static String nums;
  static String filter;
  static String[] map = {"abc", "def", "ghi", "jkl", "mno", "pqr", "st", "uv", "wx", "yz"};

  static ArrayList<String> result = new ArrayList<>();

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    nums = sc.nextLine();
    filter = sc.nextLine();

    System.out.println(getResult());
  }

  public static String getResult() {
    // 回溯算法求组合
    dfs(0, new LinkedList<>());

    // 拼接结果字符串
    StringBuilder sb = new StringBuilder();
    result.forEach(s -> sb.append(s).append(","));
    return sb.toString();
  }

  /**
   * 回溯算法求组合
   *
   * @param level 组合的层级
   * @param path 记录组合字符串
   */
  public static void dfs(int level, LinkedList<Character> path) {
    // 组合层数到达要求时&#xff0c;当前组合字符串完成
    if (level == nums.length()) {
      HashSet<Character> set = new HashSet<>(path);

      for (int i = 0; i < filter.length(); i++) {
        if (!set.contains(filter.charAt(i))) {
          StringBuilder sb = new StringBuilder();
          path.forEach(sb::append);
          result.add(sb.toString());
          return;
        }
      }

      return;
    }

    // 当前层级的数字
    int num = nums.charAt(level) - '0';
    // 该数字关联的多个字母
    String letters = map[num];

    // 遍历当前层级可选的字母
    for (int i = 0; i < letters.length(); i++) {
      // 选择字母加入当前组合
      char letter = letters.charAt(i);

      path.addLast(letter);
      // 继续组合下一个层级的字母选择
      dfs(level + 1, path);
      path.removeLast();
    }
  }
}


Python算法源码

# 输入获取
numsStr = input()
filterStr = input()

dic = ["abc", "def", "ghi", "jkl", "mno", "pqr", "st", "uv", "wx", "yz"]
result = []


# 算法入口
def getResult():
    # 回溯算法求组合
    dfs(0, [])
    # 拼接结果字符串
    return ",".join(result) + ","


def dfs(level, path):
    """
    回溯算法求组合
    :param level: 组合的层级
    :param path: 记录组合字符串
    """
    if level == len(numsStr):  # 组合层数到达要求时&#xff0c;当前组合字符串完成
        pathSet = set(path)

        for c in filterStr:
            if c not in pathSet:
                result.append("".join(path))
                return

        return

    # 当前层级的数字
    num = ord(numsStr[level]) - ord('0')
    # 该数字关联的多个字母
    letters = dic[num]

    # 遍历当前层级可选的字母
    for letter in letters:
        # 选择字母加入当前组合
        path.append(letter)
        # 继续组合下一个层级的字母选择
        dfs(level + 1, path)
        path.pop()


# 算法调用
print(getResult())


C算法源码

#include <stdio.h>
#include <string.h>

#define MAX_SIZE 6

char nums[MAX_SIZE];
char filter[MAX_SIZE];

char *map[] = {"abc", "def", "ghi", "jkl", "mno", "pqr", "st", "uv", "wx", "yz"};

void dfs(int level, char path[], int path_size) {
    // 组合层数到达要求时&#xff0c;当前组合字符串完成
    if (nums[level] == '\0') {
        int i = 0;
        while (filter[i] != '\0') {
            if (strchr(path, filter[i]) == NULL) {
                printf("%s,", path);
                return;
            }
            i++;
        }
        return;
    }

    // 当前层级的数字
    int num = nums[level] - '0';
    // 该数字关联的多个字母
    char *letters = map[num];

    // 遍历当前层级可选的字母
    int i = 0;
    while (letters[i] != '\0') {
        // 选择字母加入当前组合
        path[path_size++] = letters[i];
        // 继续组合下一个层级的字母选择
        dfs(level + 1, path, path_size);
        path_size--;
        i++;
    }
}

int main() {
    gets(nums);
    gets(filter);

    char path[MAX_SIZE] = {'\0'};

    // 回溯算法求组合
    dfs(0, path, 0);

    return 0;
}


群贤毕至

访客