按大小写选项统一字符串后,用子串查找逐行筛选包含模式串的文本。
OJ: shumeng
题目 ID: CSP201409C
难度:入门
标签:字符串模拟
日期: 2026-07-31 16:21
形式化题目
给定模式串 0 不敏感,1 敏感)和多行文本,按输入顺序输出所有包含模式串的文本行。大小写不敏感时,同一字母的大小写视为相同字符。
思路
先看手写逐位置比较的暴力:
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:21
* update_at: 2026-08-17 22:54
*/
// brute.cpp:小数据暴力解,枚举文本中的每个起点并逐字符比较。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string pattern;
int sensitive;
int n;
cin >> pattern >> sensitive >> n;
for (int i = 0; i < n; i++) {
string text;
cin >> text;
bool found = false;
for (int start = 0; start + (int)pattern.size() <= (int)text.size(); start++) {
bool same = true;
for (int j = 0; j < (int)pattern.size(); j++) {
char left = text[start + j];
char right = pattern[j];
if (!sensitive) {
if ('A' <= left && left <= 'Z') {
left = char(left - 'A' + 'a');
}
if ('A' <= right && right <= 'Z') {
right = char(right - 'A' + 'a');
}
}
if (left != right) {
same = false;
break;
}
}
if (same) {
found = true;
break;
}
}
if (found) {
cout << text << '\n';
}
}
return 0;
}每一行独立判断,不需要保存全部文本。大小写不敏感时,先把模式串和当前文本都转换为小写,再调用 find() 判断模式串是否出现;大小写敏感时直接查找原字符串。输出时保留原始文本行。
处理流程
以样例为例,模式串 Hello,敏感选项为 1:
| 文本行 | 包含 Hello? |
输出 |
|---|---|---|
| HelloWorld | 是 | 输出 |
| HiHiHelloHiHi | 是 | 输出 |
| GrepIsAGreatTool | 否 | - |
| HELLO | 否(大小写敏感) | - |
| HELLOisNOTHello | 是 | 输出 |
若把敏感选项改为 0,第 4 行 HELLO 转成小写 hello 后也能匹配,应当输出。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:21
* update_at: 2026-08-17 22:54
*/
#include <bits/stdc++.h>
using namespace std;
string lower_copy(string text) {
for (int i = 0; i < (int)text.size(); i++) {
if ('A' <= text[i] && text[i] <= 'Z') {
text[i] = char(text[i] - 'A' + 'a');
}
}
return text;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string pattern;
int sensitive;
int n;
cin >> pattern >> sensitive >> n;
if (!sensitive) {
pattern = lower_copy(pattern);
}
for (int i = 0; i < n; i++) {
string text;
cin >> text;
string target = sensitive ? text : lower_copy(text);
if (target.find(pattern) != string::npos) {
cout << text << '\n';
}
}
return 0;
}复杂度
设文本行和模式串长度上界为
总结
字符串匹配题的关键是先明确比较规则,再统一输入的表示。匹配时使用规范化后的字符串,输出时使用原字符串,就能同时满足大小写选项和原行输出要求。