相似度计算

统一将单词转为小写后分别去重,再用集合查询交集并由容斥公式得到并集。

OJ: shumeng

题目 ID: CSP202403B

难度:入门

标签:字符串集合哈希表

日期: 2026-07-31 16:21

形式化题目

给定两篇文章的单词序列,忽略英文字母大小写差异后分别得到去重集合 AABB

求两个值:

  1. AB|A \cap B|:同时出现在两篇文章中的不同单词数;
  2. AB|A \cup B|:两篇文章一共包含的不同单词数。

思路

问题本质是集合的求交与求并,难点只在于“同一个单词”的判定规则:ThetheTHE 应视为同一个单词。

大小写归一化

读入单词时先把所有大写字母转换成小写,再插入集合。归一化必须在插入集合之前完成,否则同一个单词会因写法不同被当成多个元素。

求交与求并

  • 交集:遍历集合 AA,统计其中也出现在集合 BB 里的单词个数。
  • 并集:直接由容斥公式得到
AB=A+BAB|A \cup B| = |A| + |B| - |A \cap B|。

用哈希集合存储,插入与查询都是均摊 O(1)O(1),可以应对 n,m5×105n, m \le 5 \times 10^5 的大数据。

代码

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-31 16:21
 * update_at: 2026-08-17 22:39
 */
#include <bits/stdc++.h>
using namespace std;

// 把单词统一成小写:忽略大小写差异后才能把同一个单词去重
string normalize(const string &word) {
    string result = word;
    for (int i = 0; i < (int)result.size(); i++) {
        if ('A' <= result[i] && result[i] <= 'Z') result[i] += 'a' - 'A';
    }
    return result;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;

    // 哈希集合保存两篇文章各自去重后的单词,平均 O(1) 插入与查询
    unordered_set<string> set_a, set_b;
    string word;
    for (int i = 0; i < n; i++) {
        cin >> word;
        set_a.insert(normalize(word));
    }
    for (int i = 0; i < m; i++) {
        cin >> word;
        set_b.insert(normalize(word));
    }

    // 交集大小:统计同时在两篇文章集合中出现的单词数
    int intersection = 0;
    for (unordered_set<string>::const_iterator it = set_a.begin(); it != set_a.end(); ++it) {
        if (set_b.count(*it)) intersection++;
    }

    // 并集大小由容斥公式得到:|A ∪ B| = |A| + |B| - |A ∩ B|
    cout << intersection << '\n';
    cout << set_a.size() + set_b.size() - intersection << '\n';

    return 0;
}

复杂度

设两篇文章总单词数为 N=n+mN = n + m

  • 时间:每个单词做一次大小写转换与集合插入,加上一次遍历求交集,哈希集合均摊 O(1)O(1) 操作,总时间复杂度 O(N)O(N)
  • 空间:两个集合共保存 A+B|A| + |B| 个不同单词,空间复杂度 O(A+B)O(|A| + |B|)

总结

集合统计题要先把“同一个元素”的判定规则想清楚。本题的要点是大写归一化必须在去重前完成,随后交集与并集分别通过集合查询和容斥公式一步求出,用哈希集合即可高效处理大输入。