题目 :求出文本的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;
}
890



被折叠的 条评论
为什么被折叠?



