首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/635/E
来源:牛客网
题目如下:
看完题目之后就有两个问题摆在面前:
(1)题目输入的是一串英文,怎么把一串英语拆分成一个个单词;
(2)用什么来存储每个单词的频率(用数组?数组下标只能是正整数诶。。)
只要解决了这两个问题,题目不就做出来了吗。。
下面就来解决这两个问题!
第一个问题,把一串英文拆分成一个个单词:
由于英文中有空格,所以我们可以用string类型配合getline来存贮字符串(不要问我为什么不用char)
string str;
getline(cin,str);
然后来介绍一种拆分英语的方法:stringstream
至于stringstream的用法可以找其他博客
下面是拆分单词的代码:
stream<<s1;
while(stream>>str){
···
}
这串代码可以形象的解释为:
把s1字符串全部放入一个流里面,然后通过while循环每次输出一个单词(由于此输出流遇到空格会停止输出)(在此只介绍一下,至于stringstream的功能可以自己去挖掘)
举个stringstream例子:
#include <bits/stdc++.h>
using namespace std;
stringstream str;
int main(){
string b,a="hello world hello you";
str<<a;
while(str>>b){
cout<<":";
cout<<b<<endl;
}
}
输出:
:hello
:world
:hello
:you
看了这个例子有没有体会。
ps:当你使用同一stringstream类型的str进行多次转换时,一定要记得加上
str.clear();
比如:
#include <bits/stdc++.h>
using namespace std;
stringstream str;
map<string,string> map1;
int main(){
string b,c;
string d="what is that";
string a="hello world hello you";
str<<a;
while(str>>b){
cout<<":";
cout<<b<<endl;
}
str.clear();
str<<d;
while(str>>c){
cout<<":";
cout<<c<<endl;
}
}
输出:
:hello
:world
:hello
:you
:what
:is
:that
你可以试一试把中间那个str.clear()去掉看看会发生什么。
忘记说了,字符串忽略大小写,可以先将原来的一句英语全部变成大写或者小写,然后再来分割单词,用transform或者遍历都可以
第二个问题,用什么来存储每个单词的频率:
废话不多说,可以用比较高级的“数组”------STL库的map
为啥说map是高级的数组
要知道数组的下标只能为非负整数
而map可以实现
a[“hello”]=1,b[‘A’]=2,c[-3.6]=3;
因为数组的键值只能为非负整数(a[1],a[2]),而map的键值可以为任何类型!
map插入的方法可以像数组赋值一样(每赋一个值,map容器的size就加1,map容器实值初始值为0)
map的定义和pair差不多,比如:
map<double,int> map1;
pair<double,int> pair1;
在map的定义中,尖括号内第一个数据类型为map的键值(类比数组下标);
第二个数据类型才是map的实值(类比数组的存储类型)。
可以用auto来循环遍历map1内的元素
for(auto i:map1)
在这种情况下
i.first 访问map内元素i的下标;i.second访问map内元素i的的值。
map<string,int> a;
//string类型的键值,int类型的实值
cout<<a.size(); //=0;
cout<<a["nihao"] //=0;
cout<<a.size(); //=1;
a["nihao"]=5;
cout<<a.size(); //=1;
cout<<a["nihao"].first<<endl; //=nihao;
cout<<a["nihao"].second<<endl; //=5
我们可以用键值当做单词类型,实值代表此单词的频率,配合pair(first为第一串英文单词频率,second为第二串单词频率),初始值都为0,可以放心使用自加;
最后得到了两段英文各个单词的频率,按照题目公式套用求解即可(用double类型)
代码如下:
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <map>
#include <cmath>
using namespace std;
typedef pair<int,int> P;
stringstream stream;
map<string,P> map1;
string s1,str;//s1存一条英文语句,str存单词
double x1=0,x2=0,x3=0;
void analyse(int d){//这个函数用来统计单词频率,参数d用来判断这是第几条英文语句(一共两条)
getline(cin,s1);//输入一行
transform(str.begin(),str.end(),str.begin(),::tolower);//transform函数在此用来统一此英文语句内单词为小写
stream<<s1;//输入到stream内
while(stream>>str)//每次向str输送一个单词
d==1?map1[str].first++:map1[str].second++;//统计个数,map[str]对应str所存单词的频率
stream.clear();//一定要记得清空stream
return;
}
int main(){
analyse(1);//输入并统计第一句英文单词数目
analyse(2);//输入并统计第二句英文单词数目
//以下都是计算cos值
for(auto c:map1){
x1+=c.second.first*c.second.second;
x2+=pow(c.second.first,2);x3+=pow(c.second.second,2);
}
if(x1/sqrt(x2*x3)>=0.9) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}