線上程式設計題-計算文字的 TFIDF值
阿新 • • 發佈:2019-02-14
題目 :求出文字的TFIDF
TFIDF = TF * IDF (TFIDF值越大,說明該詞可以很好的區分檔案,預測主題能力越強)
IF(詞頻) = (該詞在檔案中出現的次數)/(檔案總的詞數)
IDF(逆向檔案頻率) = log2[(總檔案數)/(該詞出現的檔案數目)];
輸入:2 //代表總的檔案數
s,t //每一行代表一個檔案
s,f
輸出 :0.00,0.50 //輸出保留兩位小數,中間用逗號隔開
0.00,0.50
解題思路:主要用map容器計算字元在每行出現的次數,和出現總的行數;
其中出現的行數要做一下判斷,一行中出現多次的字元只統計一次, 解決了這個問題,就可以直接套公式了,剛開始題目對公式寫的不是很清楚,對公式也不是很理解,所以當時沒有做出來,傷心~~~,在這做一下總結。
參考程式碼:
#include<iostream> #include<vector> #include<string> #include<map> #include <iomanip> #include<math.h> using namespace std; int main() { int n; cin >> n; //輸入檔案個數 vector<string> str(n, ""); map<char, int> mapNums;//統計每一行字元出現的個數 map<char, int> mapRows; //統計字元總共出現了幾行 for (int i = 0; i < n; i++) cin >> str[i];//讀取字串 int rowNum = 0;//統計每個字元出現的行數 for (int i = 0; i < n; i++) { for (int j = 0; j < str[i].length(); j = j + 2) { if (mapRows[str[i][j]] == 0 || (mapRows[str[i][j]] != 0 && i != rowNum))//當這個字元value值大於1,且不在同一行時,進行加1操作 { mapRows[str[i][j]]++; rowNum = i; } } } for (int i = 0; i < n; i++) { int count = 0; //每一行字元的個數 for (int j = 0; j < str[i].length(); j = j + 2) { mapNums[str[i][j]]++;//統計每一行字元出現的個數 count++; } for (int j = 0; j < str[i].length(); j = j + 2) { double IF = mapNums[str[i][j]] * 1.0 / count;//計算TF double num = mapRows[str[i][j]]; //計算字元出現的行數 double IDF = log2(n / num);//計算IDF double IFIDF = IF * IDF; cout.setf(ios::fixed);//固定保持兩個小數 j == 0 ? cout << fixed << setprecision(2) << IFIDF : cout << "," << fixed << setprecision(2) << IFIDF; } cout << endl; mapNums.clear(); } return 0; }