P1308 统计单词数
📋题意:给定一个单词 t 和一行文本 s,求 t 在 s 中作为独立单词出现的次数及首次位置(不区分大小写)。
🔑关键点:1. 统一转小写比较 2. "独立单词"意味着前后必须是空格或首尾边界 3. 用 find 或手动匹配
举例:单词 t="To",文本 s="to be or not to be"。统一转小写后 t="to",在 s 中搜索 " to "(前后加空格),找到 2 次,首次出现在位置 14(原串下标)。
#include <iostream>
#include <string>
using namespace std;
int main() {
string t; getline(cin, t);
string s; getline(cin, s);
for(auto& c:t) c=tolower(c);
for(auto& c:s) c=tolower(c);
s = " " + s + " "; t = " " + t + " ";
int cnt=0, pos=-1;
size_t p = s.find(t);
while(p != string::npos) {
cnt++; if(pos==-1) pos = p;
p = s.find(t, p+1);
}
if(cnt) cout<<cnt<<" "<<pos-1<<endl;
else cout<<-1<<endl;
}
🎯技巧:前后加空格,用 find(" t ")确保是独立单词。
P1603 斯诺登的密码
📋题意:从一段英文文本中提取所有英文数字单词(one~nineteen, twenty, thirty...ninety),转为对应数字,排序后拼接输出(去掉前导零)。
🔑思路:1. 逐词读取,去掉标点 2. 用 map 把英文单词映射为数字 3. 收集所有数字排序 4. 拼接输出
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
map<string,int> mp;
mp["one"]=1; mp["two"]=2; mp["three"]=3; mp["four"]=4; mp["five"]=5;
mp["six"]=6; mp["seven"]=7; mp["eight"]=8; mp["nine"]=9; mp["ten"]=10;
mp["eleven"]=11; mp["twelve"]=12; mp["thirteen"]=13; mp["fourteen"]=14; mp["fifteen"]=15;
mp["sixteen"]=16; mp["seventeen"]=17; mp["eighteen"]=18; mp["nineteen"]=19;
mp["twenty"]=20; mp["thirty"]=30; mp["forty"]=40; mp["fifty"]=50;
mp["sixty"]=60; mp["seventy"]=70; mp["eighty"]=80; mp["ninety"]=90;
vector<int> nums;
string w;
while(cin>>w) {
while(w.size()&&!isalpha(w.back())) w.pop_back();
while(w.size()&&!isalpha(w.front())) w.erase(w.begin());
for(auto&c:w) c=tolower(c);
if(mp.count(w)) nums.push_back(mp[w]);
}
sort(nums.begin(), nums.end());
string res;
for(int x:nums) res += to_string(x);
int st=0;
while(st<res.size()-1&&res[st]=='0') st++;
cout<<res.substr(st)<<endl;
}
🎯总结:字符串题核心——清洗(去标点、统一大小写)+ 匹配(find/map)+ 构造结果。