[STL]余弦定理
来源:互联网 发布:淘宝怎么上货 编辑:程序博客网 时间:2024/05/16 01:53
Problem C: 余弦定理
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 338 Solved: 76
[Submit][Status][Web Board]
Description
小Q在埃森哲工作有一段时间了,他觉得自己在一个岗位山做的时间有点长, 所以刚刚换了一个team,是一个搞数据挖掘文本处理的team。在文本挖掘领域,经常要将文本抽象为一个向量,而计算两个文本的相似度就是计算这两个向量的夹角。
现在我们具体的介绍如何将两段文本向量化后求取相似度:
1. 首先统计每个文本中所有词出现的频度,对于["I", "like", "nice", "girls"],可以得到频度向量("I":1, "like":1, "nice":1, "girls":1)。类似的,对于["I", "like", "strong", "boys"],则可以得到频度向量("I":1, "like":1, "strong":1, "boys":1)。
2. 可以发现两个向量的值完全相同,但是其中所代表的含义完全不相同,所以我们还需要对两个向量做对齐操作,即对各自向量添加一些空项。则两个新向量为("I":1, "like":1, "nice":1, "girls":1, "strong":0, "boys":0)和("I":1, "like":1, "nice":0, "girls":0, "strong":1, "boys":1)。
3. 使用余弦定理对两个向量(1, 1, 1, 1, 0, 0)和(1, 1, 0, 0, 1, 1)求夹角,近似表示两个文本的近似度。
Sim(A, B) = (A[0]*B[0]+A[1]*B[1]+...+A[n]*B[n])/(sqrt(A[0]*A[0]+A[1]*A[1]+...+A[n]*A[n])*sqrt(B[0]*B[0]+B[1]*B[1]+...+B[n]*B[n]))。
现在给你两段文本A和B,希望你用如上所述的方法计算Sim(A, B)。
Input
多组测试数据。每组数据两行。
第1行:输入一个文本A,文本由若干单词组成。
第2行: 输入一个文本B,文本由若干单词组成。
所有单词都只由英文大小写字母构成,相邻单词由一个空格隔开。
Output
对于每组数据。输出一行,包含一个保留小数点后两位的浮点数,代表Sim(A, B)。
Sample Input
I like strong boysI like nice girls
Sample Output
0.50
HINT
输入比较困难,可以先读入一行到临时空间,再用sprintf或strstream来格式化。其余就比较简单了。
格式化版本:
#include <cmath>#include <cstdio>#include <iostream>#include <strstream>#include <map>using namespace std;inline int getint(){int res=0;char tmp;bool sgn=1;do tmp=getchar();while (!isdigit(tmp)&&tmp!='-');if (tmp=='-'){sgn=0;tmp=getchar();}do res=(res<<3)+(res<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?res:-res;}map<string,int> h1;map<string,int> h2;char word[10000000];bool work(map<string,int> &hash){string line;string word;strstream ss1;getline(cin,line);if (cin.eof()) return false;ss1 << line;while (!ss1.eof()){ss1 >> word;hash[word]++;}return true;}map<string,int>::iterator it1;map<string,int>::iterator it2;int main(){freopen("c.in","r",stdin);freopen("c.out","w",stdout);bool first = true;for (;;){h1.clear();h2.clear();if (!work(h1)) break;work(h2);if (!first)printf("\n");first = false;int fenzi = 0;int fenmu1 = 0;int fenmu2 = 0;string tmp;for (it1=h1.begin();it1!=h1.end();it1++){fenmu1 += it1->second*it1->second;}for (it1=h2.begin();it1!=h2.end();it1++){fenmu2 += it1->second*it1->second;}for (it1=h1.begin();it1!=h1.end();){tmp = it1->first;it2 = h2.find(tmp);if (it2!=h2.end()){fenzi += it1->second*it2->second;h2.erase(it2);}it2 = it1;it1 ++;h1.erase(it2);}for (it2=h2.begin();it2!=h2.end();){tmp = it2->first;it1 = h1.find(tmp);if (it1!=h1.end()){fenzi += it1->second*it2->second;h1.erase(it1);}it1 = it2;it2 ++;h2.erase(it1);}//printf("%.2f\n",sqrt(double(fenmu1)));printf("%.2f",double(fenzi)/(sqrt(double(fenmu1))*sqrt(double(fenmu2))));}return 0;}
手动处理版本:
#include <cmath>#include <cstdio>#include <string>#include <cstring>#include <iostream>#include <map>using namespace std;inline int getint(){ int res=0;char tmp;bool sgn=1; do tmp=getchar(); while (!isdigit(tmp)&&tmp!='-'); if (tmp=='-'){sgn=0;tmp=getchar();} do res=(res<<3)+(res<<1)+tmp-'0'; while (isdigit(tmp=getchar())); return sgn?res:-res;}map<string,int> h1;map<string,int> h2;char word[10000000];bool work(map<string,int> &hash){ for(;;) { for (;;) { int tt = scanf("%[^\n ]",word); if (tt == EOF) return false; if (tt == 0) getchar(); else break; } hash[string(word)] ++; if (getchar() == '\n') break; } return true;}map<string,int>::iterator it1;map<string,int>::iterator it2;int main(){ bool first = true; for (;;) { h1.clear(); h2.clear(); if (!work(h1)) break; work(h2); if (!first) printf("\n"); first = false; int fenzi = 0; int fenmu1 = 0; int fenmu2 = 0; string tmp; for (it1=h1.begin();it1!=h1.end();it1++) { fenmu1 += it1->second*it1->second; } for (it1=h2.begin();it1!=h2.end();it1++) { fenmu2 += it1->second*it1->second; } for (it1=h1.begin();it1!=h1.end();) { tmp = it1->first; it2 = h2.find(tmp); if (it2!=h2.end()) { fenzi += it1->second*it2->second; h2.erase(it2); } it2 = it1; it1 ++; h1.erase(it2); } for (it2=h2.begin();it2!=h2.end();) { tmp = it2->first; it1 = h1.find(tmp); if (it1!=h1.end()) { fenzi += it1->second*it2->second; h1.erase(it1); } it1 = it2; it2 ++; h2.erase(it1); } //printf("%.2f\n",sqrt(double(fenmu1))); printf("%.2f",double(fenzi)/(sqrt(double(fenmu1))*sqrt(double(fenmu2)))); } return 0;}
0 0
- [STL]余弦定理
- 余弦定理
- 正弦定理和余弦定理
- 一句话证明余弦定理
- Poj3029(枚举+余弦定理)
- 三角形余弦定理
- 正弦余弦定理
- 余弦定理----相似性计算
- hdu 2080 余弦定理
- 正余弦定理
- 正余弦定理公式
- 余弦定理的三个证明
- 余弦定理和新闻分类
- 相似度算法:余弦定理
- 余弦定理和新闻的分类
- 余弦定理和新闻的分类
- 根据余弦定理求两个线段夹角
- 余弦定理和新闻的分类
- HTML Button.onclick 事件汇总
- How to solve JAVA Version and Manifest problem?
- C# 基础知识 (二).独特的知识及用法篇
- 单态设计模式(Singleton Design Pattern)
- Winter Break
- [STL]余弦定理
- 常用经典SQL语句
- SQL2000数据库查询讲解001--基本表的建立
- IIS没有.net版本选择标签问题
- SI Object Browser 联接oracle 11g出错
- ext3 swf组件模式实现多选文件上传
- a href=#与 a href=javascript:void(0) 的区别
- VIM常用快捷键搜集
- $_SERVER['PHP_SELF']和$_SERVER['SCRIPT_NAME']区别