Day6 备战CCF-CSP练习

佚名 / 2024-10-13 / 原文

Day 6

题目描述

给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行。

你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符;当选项关闭时,表示同一个字母的大写和小写看作相同的字符。

输入格式

输入的第一行包含一个字符串 \(S\),由大小写英文字母组成。

第二行包含一个数字,表示大小写敏感的选项,当数字为 \(0\) 时表示大小写不敏感,当数字为 \(1\)时表示大小写敏感。

第三行包含一个整数 \(n\),表示给出的文字的行数。

接下来 \(n\) 行,每行包含一个字符串,字符串由大小写英文字母组成,不含空格和其他字符。

输出格式

输出多行,每行包含一个字符串,按出现的顺序依次给出那些包含了字符串 \(S\) 的行。

数据范围

\(1≤n≤100\),每个字符串的长度不超过 \(100\)

输入样例:

Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello

输出样例:

HelloWorld
HiHiHelloHiHi
HELLOisNOTHello

样例解释

在上面的样例中,第四个字符串虽然也是 Hello,但是大小写不正确。

如果将输入的第二行改为 \(0\),则第四个字符串应该输出。

题目分析

字符串匹配,由于数据很小,双指针暴力也可以拿满分,若数据量很大,用\(KMP\)优化即可
至于大小写,spj一下就行了

C++ 代码

暴力

#include<bits/stdc++.h>

using namespace std;

string s;
int lower;
int n;

int main()
{
    cin >> s >> lower >> n;
    
    if(!lower)
        for(auto &it : s)
            it = tolower(it);
    
    string p;
    vector<string> res;
    while (n -- )
    {
        cin >> p;
        auto r = p;
        if(!lower) 
            for(auto &it : p)
                it = tolower(it);
                
        for(int j = 0 ; j < p.size() ; j ++){
            int i = 0 , k = j;
            for(; i < s.size() && k < p.size() ; i ++ , k ++)
                if(s[i] != p[k]) break;
            if(i == s.size()){
                res.push_back(r);
                break;
            }
               
        }
    }
    
    for(auto str : res)
        cout << str << '\n';
    
}

\(KMP\)

#include <bits/stdc++.h>

using namespace std;
const int N = 110;

int lower , T;
char s[N] , p[N] , r[N];
int ne[N];

int main()
{
    cin >> s + 1  >> lower>> T;
    int n = strlen(s + 1);
    
    if(!lower)
        for(int i = 1 ; i <= n ; i ++)
            s[i] = tolower(s[i]);
    
    for(int i = 2 , j = 0 ; i <= n ; i ++)
    {
        while(j && s[i] != s[j + 1]) j = ne[j];
        if(s[i] == s[j + 1]) j ++;
        ne[i] = j;
    }
    
    while (T -- )
    {
        cin >> p + 1;
        int m = strlen(p + 1);
        
        memcpy(r , p , sizeof p);
        
        if(!lower)
            for(int i = 1 ; i <= m ; i ++)
                p[i] = tolower(p[i]);
        
        for(int i = 1 , j = 0 ; i <= m ; i ++)
        {
            while(j && p[i] != s[j + 1]) j = ne[j];
            if(p[i] == s[j + 1]) j ++;
            if(j == n)
            {
                for(int k = 1 ; k <= m ; k ++)
                    cout << r[k];
                cout << endl;
                break;
            }
        }
    }
}