题目
时间限制:1s 内存限制:256MB
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的单词位置,若不存在则输出-1。
注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同,如果给定单词仅是文章中某一单词的一部分则不算匹配。
输入数据
第1行为一个字符串,其中只可能包含字母和空格,表示给定的文章;
第2行为一个正整数n,代表询问次数;
接下来n行,每行有一个字符串,其中只包含字母,表示要查找的单词。
输出数据
输出共n行,每行包含该单词出现的次数以及该单词第一次出现的位置
输入样例
to be or not to be is a question
2
Be
quest
输出样例
2 1
-1
说明
“Be”不区分大小的第一次出现位置为第1个单词(从0开始计数),总共出现了两次(第1个和第5个),因此第一行输出为2 1
“quest”在文本中没有完全相同的单词,因此第二行输出-1
对于30%的数据:1≤查找的单词长度≤第一行字符串长度≤103,1≤𝑛≤102
对于60%的数据:1≤查找的单词长度≤第一行字符串长度≤105,1≤𝑛≤2×103
对于100%的数据:1≤查找的单词长度≤第一行字符串长度≤106,1≤𝑛≤104
思路
模拟题,模拟思路很简单
对于一个转化成全小写的单词
分别记录(1)首次出现的位置(2)出现次数
本题选用<map>头文件最佳,设立两个map<string,int>,分别表示“单词-首次出现位置”和“单词-出现次数”。
代码
#include<iostream>
#include<map>
#include<cctype>
#include<string>
using namespace std;
int main(){
map<string,int> cnt; \\单词-出现次数
map<string,int> pos; \\单词-首次出现位置
int posi=0;
while(cin.peek()!='\n'){ \\读取一行的单词方法
string temp;
cin>>temp;
for(char& c:temp){ \\对于temp每个字符遍历,转化为小写
c=tolower(c); \\char&表示直接改变原字符
}
if(cnt[temp]==0){ \\temp在之前还未出现过
pos[temp]=posi; \\记录当前位置
}
cnt[temp]++; \\temp已出现过+1;temp未出现过则创建<temp,0>,再key++
posi++;
}
int n;
cin>>n;
while(n--){
string check;
for(char& c:check){
c=tolower(c);
}
if(cnt[check]==0){
cout<<-1<<endl;
} else {
cout<<cnt[check]<<' '<<pos[check]<<endl;
}
}
return 0;
}
心得
(1)记录pos必须在cnt++之前,因为要表示之前未出现过,如果cnt先++,则将当前情况也做了计数。则判断失效了,无法得知在这个节点之前的状态。
(2)temp之前从未出现过=="cnt[temp]==0"
(3)读取一行==while(cin.peek()!='\n')
(4)map的表示方法MyMap[value]=key