7-44 基於詞頻的文件相似度 (30分)


實現一種簡單原始的文件相似度計算,即以兩文件的公共詞匯占總詞匯的比例來定義相似度。為簡化問題,這里不考慮中文(因為分詞太難了),只考慮長度不小於3、且不超過10的英文單詞,長度超過10的只考慮前10個字母。

輸入格式:

輸入首先給出正整數N(≤),為文件總數。隨后按以下格式給出每個文件的內容:首先給出文件正文,最后在一行中只給出一個字符#,表示文件結束。在N個文件內容結束之后,給出查詢總數M(≤),隨后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%

用map統計,不過注意一點map在查詢時會改變其size().
代碼:
#include <cstdio>
#include <algorithm>
#include <map>
#include <cctype>
using namespace std;

int n,m;
char s[11],ch;
int com[101][101],num[101],sn;
map<string,bool> mp[101];
int main() {
    scanf("%d",&n);
    for(int i = 1;i <= n;i ++) {
        while((ch = tolower(getchar())) != '#') {
            if(ch >= 'a' && ch <= 'z') {
                if(sn < 10) s[sn ++] = ch;
            }
            else {
                s[sn] = 0;
                if(sn > 2) mp[i][s] = 1;
                sn = 0;
            }
        }
        for(map<string,bool>::iterator it = mp[i].begin();it != mp[i].end();it ++) {
            for(int j = 0;j < i;j ++) {
                com[i][j] = com[j][i] += mp[j][it -> first];
            }
        }
        com[i][i] = num[i] = mp[i].size();
    }
    scanf("%d",&m);
    int a,b;
    for(int i = 0;i < m;i ++) {
        scanf("%d%d",&a,&b);
        printf("%.1f%%\n",com[a][b] * 100.0 / (num[a] + num[b] - com[a][b]));
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM