循序渐进,刚开始做一些简单的题热身。
这道题大意是有t个test case, 每个case第一个doc是search string, 包含一些term。
然后后面有多个doc,计算结果是doc中每个term出现的次数和它在search string中出现次数乘积的方差。
题目意思简单,容易处理,但是有三个地方需要注意:
1. 删除term中的标点符号,标点符号不进行比较。
2. 进行比较时不区分大小写。
3. 空的term不进行计数(只有标点符号的term删除标点后为空)。
偷了个懒,用了c++的string写的代码,最终AC。
#include <iostream>
#include <map>
#include <cmath>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
using namespace std;
string reform(const string &str)
{
string rlt="";
int i = 0, len= str.size();
for(i=0;i<len;i++) {
if (isupper(str[i])) {
rlt += tolower(str[i]);;
} else if (islower(str[i]) || isdigit(str[i])) {
rlt += str[i];
}
}
return rlt;
}
int main()
{
#ifdef LOCAL_INPUT
freopen("data", "r", stdin);
#endif
int t;
double rlt;
string tmp;
map<string, int> terms, doc;
map<string, int>::iterator iter, iter1;
const string SEP = "----------";
cin>>t;
while(t--) {
/* search string */
terms.clear();
while(cin>>tmp && strncmp(tmp.c_str(), SEP.c_str(), 10)) {
tmp = reform(tmp);
if (tmp.empty()) continue;
iter = terms.find(tmp);
if (iter != terms.end()) {
iter->second++;
} else {
terms[tmp] = 1;
}
}
/* documents */
doc.clear();
while(cin>>tmp) {
if (!strncmp(tmp.c_str(), SEP.c_str(), 10)) {
/* end of a document */
rlt = 0.0;
for(iter = terms.begin(); iter!=terms.end();iter++) {
iter1 = doc.find(iter->first);
if (iter1 != doc.end()) {
rlt += sqrt(1.0 *iter->second * iter1->second);
}
}
printf("%.2f\n", rlt);
doc.clear();
/* check one more line */
cin>>tmp;
if (!strncmp(tmp.c_str(), SEP.c_str(), 10))
break;
}
tmp = reform(tmp);
if (tmp.empty()) continue;
iter = doc.find(tmp);
if (iter != doc.end()) {
iter->second++;
} else {
doc[tmp] = 1;
}
}
if (t) cout<<endl;
}
}