1. 程式人生 > >線上程式設計題-計算文字的 TFIDF值

線上程式設計題-計算文字的 TFIDF值

題目 :求出文字的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;
}