基于词频的文件相似度 (30分)

实现一种简单原始的文件相似度计算,即以两文件的公共词汇占总词汇的比例来定义相似度。为简化问题,这里不考虑中文(因为分词太难了),只考虑长度不小于3、且不超过10的英文单词,长度超过10的只考虑前10个字母。
输入格式:

输入首先给出正整数N(≤100),为文件总数。随后按以下格式给出每个文件的内容:首先给出文件正文,最后在一行中只给出一个字符#,表示文件结束。在N个文件内容结束之后,给出查询总数M(≤10​4​​),随后M行,每行给出一对文件编号,其间以空格分隔。这里假设文件按给出的顺序从1到N编号。
输出格式:

针对每一条查询,在一行中输出两文件的相似度,即两文件的公共词汇量占两文件总词汇量的百分比,精确到小数点后1位。注意这里的一个“单词”只包括仅由英文字母组成的、长度不小于3、且不超过10的英文单词,长度超过10的只考虑前10个字母。单词间以任何非英文字母隔开。另外,大小写不同的同一单词被认为是相同的单词,例如“You”和“you”是同一个单词。
输入样例:

3
Aaa Bbb Ccc
#
Bbb Ccc Ddd
#
Aaa2 ccc Eee
is at Ddd@Fff
#
2
1 2
1 3

输出样例:

50.0%
33.3%

这道题还是相对来说在今天做的题里蛮简单的,只要留意ddd@aaa这种情况是两个词,可以用stringstream处理这种情况,其他的地方都跟天体二阶题<集合相似度>差不多

//
// Created by TIGA_HUANG on 2020/10/6.
//

#include <iostream>
#include <vector>
#include <set>
#include <iomanip>
#include <sstream>

using namespace std;

int N;
set<string> v[105];

int main() {
    
    
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> N;
    string str;
    for (int i = 0; i < N; ++i) {
    
    
        do {
    
    
            cin >> str;
            if (str == "#")
                continue;
            for (int j = 0; str[j]; ++j) {
    
    
                if (isupper(str[j]))
                    str[j] = str[j] - 'A' + 'a';
                if (!(isupper(str[j]) || islower(str[j]))) {
    
    
                    str[j] = ' ';
                }
            }
            stringstream ss;
            ss << str;
            while(ss >> str) {
    
    
                if (str.length() > 10) {
    
    
                    str = str.erase(10);
                    v[i + 1].insert(str);
                } else if (str.length() > 2) {
    
    
                    v[i + 1].insert(str);
                }
            }

        } while (str != "#");
    }
    int K;
    cin >> K;
    set<string> sc;
    for (int i = 0; i < K; ++i) {
    
    
        int a, b, same = 0;
        cin >> a >> b;
        for (const auto & item : v[a]) {
    
    
            if (v[b].count(item)) {
    
    
                same++;
            }
        }
        cout << fixed << setprecision(1) << same * 100.0 / (v[a].size() + v[b].size() - same) << "%\n";
        sc.clear();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44378358/article/details/108942007