当前位置:   article > 正文

【华为OD机试|02】音乐小说内容重复识别(Java/C/Py/JS)

【华为OD机试|02】音乐小说内容重复识别(Java/C/Py/JS)

目录

一、题目介绍 

1.1 题目描述

1.2 输入描述

1.3 输出描述

1.4 用例

二、题目解析

2.1 题目分析

2.2 实现思路

三、Java实现

3.1 详细代码

3.2 代码解析

四、C#实现

4.1 详细代码

4.2 代码解析

五、Python实现

5.1 完整代码

5.2 代码解析

六、JS实现

6.1 完整代码

6.2 代码解析

 

七、总结


一、题目介绍 

1.1 题目描述

实现一个简易的重复内容识别系统,通过给定的两个内容名称,和相似内容符号,判断两个内容是否相似;如果相似,返回相似内容;如果不相似,返回不相似的内容。

初始化:给出两个字符串,一些相似字符对,如顿号和逗号相似,的和de相似,猪和潴,给出两个字符串的相似判断结果

输入:两条语句,给出是否相似,对于相似的语句,返回True和相似的字符对;对于不相似的内容,则返回第一个内容的不相似信息,方便后续补充

注意:

  1. 相似关系是 具有 传递性的。例如,如果"顿号"和"逗号"是相似的,"逗号"和"分号"是相似的,则"顿号"和"逗号"是相似的。
  2. 为了过滤一些无意义的信息,这里***可以匹配任意长度的内容,例如:

    给出相似对"(****)",""时,"异世邪君(人气玄幻作家)" 和 "异世邪君" 认为是相似,此时相似符号返回 *** 即可
     
  3. 不相似的内容,需要给出不相似的字符串,多处不相似的字符串用空格分隔

1.2 输入描述

  • 第一行表示第一张专辑的专辑名,其中 0 < 专辑长度 ≤ 50
  • 第二行表示第二张专辑的专辑名,其中 0 < 专辑长度 ≤ 50
  • 第三行开始每行为相似的字符串,每行一组,每组字符串不超过10个
  • 总共相似字符串行不超过10行

1.3 输出描述

  • 第一行返回相似判断的结果,即True或者False
  • 第二行开始返回相似/不相似的字符串,每行一组

1.4 用例

输入林汉达上下五千年
林汉达上下5千年
五 5 ⑤ 伍 wu
输出True
五 5
说明
输入幸福de猪的个人专辑
幸福的猪的个人专辑
得 的
得 de
输出True
de 的
说明
输入异世邪君(人气玄幻作家)
异世邪君
(***)
输出

True

(***)

说明
输入浩然爸爸讲成语
浩然爸爸讲论语
论语 三字经
输出False
成语 论语
说明

二、题目解析

2.1 题目分析

这个题目主要考察以下几个算法和数据结构的知识:

  1. 字符串匹配和替换

    • 在判断两个字符串是否相似时,需要能够快速匹配和替换字符串中的相似字符对。
  2. 并查集(Union-Find)算法

    • 由于相似关系是传递性的,可以用并查集算法来处理这种相似关系,方便快速查找和合并相似字符的集合。
  3. 哈希表

    • 使用哈希表存储相似字符对,方便快速查找和匹配。

2.2 实现思路

  1. 读取输入:包括两个专辑名和相似字符对。
  2. 构建并查集:用并查集来处理相似字符对,构建每个字符的相似集合。
  3. 字符串归一化:根据并查集,将两个专辑名归一化,即将所有相似字符替换成它们的代表字符。
  4. 比较归一化后的字符串:判断归一化后的字符串是否相同。如果相同,返回 True 和相似字符对;否则,返回 False 和第一个专辑名中不相似的信息。

三、Java实现

3.1 详细代码

  1. import java.util.*;
  2. public class SimilarContentChecker {
  3. private static class UnionFind {
  4. private Map<String, String> parent;
  5. public UnionFind() {
  6. parent = new HashMap<>();
  7. }
  8. public String find(String x) {
  9. if (!parent.containsKey(x)) {
  10. parent.put(x, x);
  11. }
  12. if (!x.equals(parent.get(x))) {
  13. parent.put(x, find(parent.get(x)));
  14. }
  15. return parent.get(x);
  16. }
  17. public void union(String x, String y) {
  18. String rootX = find(x);
  19. String rootY = find(y);
  20. if (!rootX.equals(rootY)) {
  21. parent.put(rootX, rootY);
  22. }
  23. }
  24. }
  25. public static void main(String[] args) {
  26. Scanner scanner = new Scanner(System.in);
  27. // 读取输入
  28. String album1 = scanner.nextLine();
  29. String album2 = scanner.nextLine();
  30. List<String[]> similarPairs = new ArrayList<>();
  31. while (scanner.hasNextLine()) {
  32. String line = scanner.nextLine();
  33. if (line.isEmpty()) break;
  34. similarPairs.add(line.split(","));
  35. }
  36. // 构建并查集
  37. UnionFind uf = new UnionFind();
  38. for (String[] pair : similarPairs) {
  39. for (int i = 0; i < pair.length - 1; i++) {
  40. uf.union(pair[i], pair[i + 1]);
  41. }
  42. }
  43. // 字符串归一化
  44. String normalizedAlbum1 = normalizeString(album1, uf);
  45. String normalizedAlbum2 = normalizeString(album2, uf);
  46. // 比较归一化后的字符串
  47. if (normalizedAlbum1.equals(normalizedAlbum2)) {
  48. System.out.println("True");
  49. printSimilarPairs(similarPairs);
  50. } else {
  51. System.out.println("False");
  52. System.out.println(getDifferences(album1, normalizedAlbum1, normalizedAlbum2));
  53. }
  54. }
  55. private static String normalizeString(String s, UnionFind uf) {
  56. StringBuilder normalized = new StringBuilder();
  57. for (char c : s.toCharArray()) {
  58. String str = String.valueOf(c);
  59. normalized.append(uf.find(str));
  60. }
  61. return normalized.toString();
  62. }
  63. private static void printSimilarPairs(List<String[]> similarPairs) {
  64. for (String[] pair : similarPairs) {
  65. System.out.println(Arrays.toString(pair));
  66. }
  67. }
  68. private static String getDifferences(String original, String normalized1, String normalized2) {
  69. StringBuilder differences = new StringBuilder();
  70. for (int i = 0; i < original.length(); i++) {
  71. if (normalized1.charAt(i) != normalized2.charAt(i)) {
  72. differences.append(original.charAt(i)).append(" ");
  73. }
  74. }
  75. return differences.toString().trim();
  76. }
  77. }

3.2 代码解析

详细讲解代码实现步骤

  1. 并查集(Union-Find)类

    • UnionFind 类用于处理字符的相似关系。find 方法用于查找字符的根代表,union 方法用于合并两个字符的相似集合。
  2. 读取输入

    • 使用 Scanner 读取两个专辑名和相似字符对。
    • 将相似字符对存储在 similarPairs 列表中。
  3. 构建并查集

    • 对于每一对相似字符对,调用 union 方法将它们合并到同一个集合中。
  4. 字符串归一化

    • 遍历专辑名中的每一个字符,使用 find 方法将其归一化为相似集合的代表字符。
  5. 比较归一化后的字符串

    • 比较归一化后的两个专辑名是否相同。如果相同,输出 True 和相似字符对;否则,输出 False 和第一个专辑名中不相似的信息。

这种方法使用了并查集来高效处理相似关系,并使用哈希表进行字符查找和归一化处理,确保了算法的高效性和准确性。

四、C#实现

4.1 详细代码

  1. using System;
  2. using System.Collections.Generic;
  3. public class SimilarContentChecker
  4. {
  5. private class UnionFind
  6. {
  7. private Dictionary<string, string> parent;
  8. public UnionFind()
  9. {
  10. parent = new Dictionary<string, string>();
  11. }
  12. public string Find(string x)
  13. {
  14. if (!parent.ContainsKey(x))
  15. {
  16. parent[x] = x;
  17. }
  18. if (x != parent[x])
  19. {
  20. parent[x] = Find(parent[x]);
  21. }
  22. return parent[x];
  23. }
  24. public void Union(string x, string y)
  25. {
  26. string rootX = Find(x);
  27. string rootY = Find(y);
  28. if (rootX != rootY)
  29. {
  30. parent[rootX] = rootY;
  31. }
  32. }
  33. }
  34. public static void Main(string[] args)
  35. {
  36. string album1 = Console.ReadLine();
  37. string album2 = Console.ReadLine();
  38. List<string[]> similarPairs = new List<string[]>();
  39. string line;
  40. while (!string.IsNullOrEmpty(line = Console.ReadLine()))
  41. {
  42. similarPairs.Add(line.Split(','));
  43. }
  44. UnionFind uf = new UnionFind();
  45. foreach (var pair in similarPairs)
  46. {
  47. for (int i = 0; i < pair.Length - 1; i++)
  48. {
  49. uf.Union(pair[i], pair[i + 1]);
  50. }
  51. }
  52. string normalizedAlbum1 = NormalizeString(album1, uf);
  53. string normalizedAlbum2 = NormalizeString(album2, uf);
  54. if (normalizedAlbum1 == normalizedAlbum2)
  55. {
  56. Console.WriteLine("True");
  57. PrintSimilarPairs(similarPairs);
  58. }
  59. else
  60. {
  61. Console.WriteLine("False");
  62. Console.WriteLine(GetDifferences(album1, normalizedAlbum1, normalizedAlbum2));
  63. }
  64. }
  65. private static string NormalizeString(string s, UnionFind uf)
  66. {
  67. char[] normalized = new char[s.Length];
  68. for (int i = 0; i < s.Length; i++)
  69. {
  70. normalized[i] = uf.Find(s[i].ToString())[0];
  71. }
  72. return new string(normalized);
  73. }
  74. private static void PrintSimilarPairs(List<string[]> similarPairs)
  75. {
  76. foreach (var pair in similarPairs)
  77. {
  78. Console.WriteLine(string.Join(",", pair));
  79. }
  80. }
  81. private static string GetDifferences(string original, string normalized1, string normalized2)
  82. {
  83. List<char> differences = new List<char>();
  84. for (int i = 0; i < original.Length; i++)
  85. {
  86. if (normalized1[i] != normalized2[i])
  87. {
  88. differences.Add(original[i]);
  89. }
  90. }
  91. return string.Join(" ", differences);
  92. }
  93. }

4.2 代码解析

详细讲解代码实现步骤

  1. 并查集(Union-Find)类

    • UnionFind 类用于处理字符的相似关系。Find 方法用于查找字符的根代表,Union 方法用于合并两个字符的相似集合。
  2. 读取输入

    • 使用 Console.ReadLine() 读取两个专辑名和相似字符对。
    • 将相似字符对存储在 similarPairs 列表中。
  3. 构建并查集

    • 对于每一对相似字符对,调用 Union 方法将它们合并到同一个集合中。
  4. 字符串归一化

    • 遍历专辑名中的每一个字符,使用 Find 方法将其归一化为相似集合的代表字符。
  5. 比较归一化后的字符串

    • 比较归一化后的两个专辑名是否相同。如果相同,输出 True 和相似字符对;否则,输出 False 和第一个专辑名中不相似的信息。

五、Python实现

5.1 完整代码

  1. class UnionFind:
  2. def __init__(self):
  3. self.parent = {}
  4. def find(self, x):
  5. if x not in self.parent:
  6. self.parent[x] = x
  7. if self.parent[x] != x:
  8. self.parent[x] = self.find(self.parent[x])
  9. return self.parent[x]
  10. def union(self, x, y):
  11. rootX = self.find(x)
  12. rootY = self.find(y)
  13. if rootX != rootY:
  14. self.parent[rootX] = rootY
  15. def normalize_string(s, uf):
  16. normalized = []
  17. for char in s:
  18. normalized.append(uf.find(char))
  19. return ''.join(normalized)
  20. def get_differences(original, normalized1, normalized2):
  21. differences = []
  22. for o, n1, n2 in zip(original, normalized1, normalized2):
  23. if n1 != n2:
  24. differences.append(o)
  25. return ' '.join(differences)
  26. def main():
  27. import sys
  28. input = sys.stdin.read().strip().split('\n')
  29. album1 = input[0]
  30. album2 = input[1]
  31. similar_pairs = [line.split(',') for line in input[2:] if line]
  32. uf = UnionFind()
  33. for pair in similar_pairs:
  34. for i in range(len(pair) - 1):
  35. uf.union(pair[i], pair[i + 1])
  36. normalized_album1 = normalize_string(album1, uf)
  37. normalized_album2 = normalize_string(album2, uf)
  38. if normalized_album1 == normalized_album2:
  39. print("True")
  40. for pair in similar_pairs:
  41. print(','.join(pair))
  42. else:
  43. print("False")
  44. print(get_differences(album1, normalized_album1, normalized_album2))
  45. if __name__ == "__main__":
  46. main()

5.2 代码解析

详细讲解代码实现步骤

  1. 并查集(Union-Find)类

    • UnionFind 类用于处理字符的相似关系。find 方法用于查找字符的根代表,union 方法用于合并两个字符的相似集合。
    • __init__ 方法初始化一个空的父节点字典 parent
    • find 方法使用路径压缩来查找并更新字符的根代表。
    • union 方法合并两个字符的相似集合。
  2. 读取输入

    • 使用 sys.stdin.read() 读取输入数据,并将其按行分割成列表。
    • 前两行是两个专辑名,从第三行开始是相似字符对。
    • 将相似字符对存储在 similar_pairs 列表中。
  3. 构建并查集

    • 对于每一对相似字符对,调用 union 方法将它们合并到同一个集合中。
  4. 字符串归一化

    • normalize_string 函数遍历专辑名中的每一个字符,使用 find 方法将其归一化为相似集合的代表字符。
    • 返回归一化后的字符串。
  5. 比较归一化后的字符串

    • 比较归一化后的两个专辑名是否相同。如果相同,输出 True 和相似字符对;否则,输出 False 和第一个专辑名中不相似的信息。
    • get_differences 函数用于找出原始字符串中不相似的字符,并将它们连接成一个字符串返回。

六、JS实现

6.1 完整代码

  1. class UnionFind {
  2. constructor() {
  3. this.parent = new Map();
  4. }
  5. find(x) {
  6. if (!this.parent.has(x)) {
  7. this.parent.set(x, x);
  8. }
  9. if (this.parent.get(x) !== x) {
  10. this.parent.set(x, this.find(this.parent.get(x)));
  11. }
  12. return this.parent.get(x);
  13. }
  14. union(x, y) {
  15. let rootX = this.find(x);
  16. let rootY = this.find(y);
  17. if (rootX !== rootY) {
  18. this.parent.set(rootX, rootY);
  19. }
  20. }
  21. }
  22. function normalizeString(s, uf) {
  23. return s.split('').map(char => uf.find(char)).join('');
  24. }
  25. function getDifferences(original, normalized1, normalized2) {
  26. let differences = [];
  27. for (let i = 0; i < original.length; i++) {
  28. if (normalized1[i] !== normalized2[i]) {
  29. differences.push(original[i]);
  30. }
  31. }
  32. return differences.join(' ');
  33. }
  34. function main(input) {
  35. let lines = input.trim().split('\n');
  36. let album1 = lines[0];
  37. let album2 = lines[1];
  38. let similarPairs = lines.slice(2).map(line => line.split(','));
  39. let uf = new UnionFind();
  40. for (let pair of similarPairs) {
  41. for (let i = 0; i < pair.length - 1; i++) {
  42. uf.union(pair[i], pair[i + 1]);
  43. }
  44. }
  45. let normalizedAlbum1 = normalizeString(album1, uf);
  46. let normalizedAlbum2 = normalizeString(album2, uf);
  47. if (normalizedAlbum1 === normalizedAlbum2) {
  48. console.log("True");
  49. for (let pair of similarPairs) {
  50. console.log(pair.join(','));
  51. }
  52. } else {
  53. console.log("False");
  54. console.log(getDifferences(album1, normalizedAlbum1, normalizedAlbum2));
  55. }
  56. }
  57. // Example usage:
  58. const input = `albumOne
  59. albumTwo
  60. a,b
  61. b,c
  62. c,d`;
  63. main(input);

6.2 代码解析

详细讲解代码实现步骤

  1. 并查集(Union-Find)类

    • UnionFind 类用于处理字符的相似关系。find 方法用于查找字符的根代表,union 方法用于合并两个字符的相似集合。
    • constructor 初始化一个空的 Map 对象 parent
    • find 方法使用路径压缩来查找并更新字符的根代表。
    • union 方法合并两个字符的相似集合。
  2. 读取输入

    • 使用 trim().split('\n') 读取输入数据,并将其按行分割成列表。
    • 前两行是两个专辑名,从第三行开始是相似字符对。
    • 将相似字符对存储在 similarPairs 列表中。
  3. 构建并查集

    • 对于每一对相似字符对,调用 union 方法将它们合并到同一个集合中。
  4. 字符串归一化

    • normalizeString 函数遍历专辑名中的每一个字符,使用 find 方法将其归一化为相似集合的代表字符。
    • 返回归一化后的字符串。
  5. 比较归一化后的字符串

    • 比较归一化后的两个专辑名是否相同。如果相同,输出 True 和相似字符对;否则,输出 False 和第一个专辑名中不相似的信息。
    • getDifferences 函数用于找出原始字符串中不相似的字符,并将它们连接成一个字符串返回。

七、总结

 这道题目要求我们实现一个系统,用于判断两个字符串是否相似,并且在相似时返回相似的字符对,在不相似时返回第一个字符串中的不相似信息。主要用到了并查集(Union-Find)算法来处理字符的相似关系

下期见啦~ 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/777023
推荐阅读
相关标签
  

闽ICP备14008679号