CCF CSP认证历年题目自练Day38

news2024/7/4 4:38:14

题目

试题编号: 201409-3
试题名称: 字符串匹配
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行。你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符;当选项关闭时,表示同一个字母的大写和小写看作相同的字符。
输入格式
  输入的第一行包含一个字符串S,由大小写英文字母组成。
  第二行包含一个数字,表示大小写敏感的选项,当数字为0时表示大小写不敏感,当数字为1时表示大小写敏感。
  第三行包含一个整数n,表示给出的文字的行数。
  接下来n行,每行包含一个字符串,字符串由大小写英文字母组成,不含空格和其他字符。
输出格式
  输出多行,每行包含一个字符串,按出现的顺序依次给出那些包含了字符串S的行。
样例输入
Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello
样例输出
HelloWorld
HiHiHelloHiHi
HELLOisNOTHello
样例说明
  在上面的样例中,第四个字符串虽然也是Hello,但是大小写不正确。如果将输入的第二行改为0,则第四个字符串应该输出。
评测用例规模与约定
  1<=n<=100,每个字符串的长度不超过100。

题目分析(个人理解)

  1. 其实,这题目就告诉我们要考什么内容了,对于字符串的匹配有两种算法,第一种,BF算法,也就是朴素算法。还有一种,KMP算法。
  2. 由于测试长度较小,可以遍历比较,也就是BF算法足以。可以利用python的.find()方法实现查找,该函数会返回模式串第一个字符在母串的位置,如果不存在则返回-1。第一行输入的是模式串,第二行输入开关(1就是区分大小写,0不区分),第三行输入有n个母串,之后的n行输入n个母串,如果不区分大小写,可将母串与模式串都转化成大写或小写,然后判断是否匹配即可(使用.upper()方法可将字符串小写字母全部转为大写)。如果区分大小写,单用find()方法,判断是否存在即可。
  3. 最后输出存在的匹配的母串即可,上代码!!!
#朴素算法
s=input().strip()
m=int(input())
n=int(input())
for i in range(n):
    #枚举每一个字母,扫描每一个位置并且判断是否匹配
    x=input().strip()
    if m==1 :
        if x.find(s)!=-1:
            print(x)
    else:
        if x.upper().find(s.upper())!=-1:
            print(x)
  1. 模式匹配问题:就是在一篇长度为n的文本S中,查找某个长度为m的关键词P,称S为母串,P为模式串。P可能出现多次,都需要找到。
  2. BF算法是一种暴力解法,复杂度至少O(m+n),从S的第一个字符开始,逐个匹配P的每一个字符,如果发现不同就从S的下一个字符重新开始匹配。暴力方法哪里不好?遇到恶劣一点的模式串,如果模式串在匹配的时候一直到最后一个字符才匹配失败,那复杂度直接退化成O(nm)。所以说这种算法很不稳定。之后进化出了KMP算法。
  3. KMP算法是一种在任何情况下都可以达到O(m+n)复杂度的算法。我在介绍朴素算法的时候,,就是在匹配失败的时候指向P的指针j都要回溯到0,也就是又要从模式串第一个开始匹配,指向S的指针i都要回溯,这也就是弊端。
  4. 对于字符串的样子在匹配的时候可以分类,第一类,P在失配点之前的每个字符都不相同,在这种情况下可以直接把P滑动到S的i位置,此时i不变,j回溯到0,然后直接下一步匹配。第二类,P在失配点之前的字符有部分相同,关键是相同的部分在哪里,这又可以分为两种情况,相同的部分是前缀(在P的最前面)和后缀。假如在i号位失配,前缀与后缀相同时可以将P的前缀的后一位滑动到S的i号位做比较即可。第二种情况,相同的部分不是前缀或后缀,那只能按照第一类去判断,j回溯到i的位置在做匹配的判断。
  5. 好了,根据第七点我的解释,现在我们只需要找到最长公共前后缀和,也就是出现第二类的第一种情况的时候如何解决,第一类和第二类的第二种情况当匹配失败的时候只需要将j回溯到i即可。完全不需要回溯i,关键在于计算p的前缀和后缀。
  6. Next[]数组的计算:例:P = “abcaab”,计算过程如下表,每一行的下划线串是最长公共前后缀。在这里插入图片描述
    计算Next[]:复杂度O(m)的方法,利用前缀和后缀的关系,从Next[i]递推到Next[i+1]。
    假设已经算出Next[i],它对应P[0]~P[i-1]这部分子串的后缀和前缀。
    阴影部分w是最长交集,交集w的长度等于Next[i]。
    上半部分的阴影所示的后缀的最后一个字符是P[i-1];
    下半部分阴影所示前缀的第一个字符是P[0],最后一个字符是P[j],j = Next[i]-1。

在这里插入图片描述
推广到Next[i+1],它对应P[0]~P[i]的后缀和前缀。
此时后缀的最后一个字符是P[i],与这个字符相对应,把前缀的j也往后移一个字符,j = Next[i]。判断两种情况:
(1)若P[i] = P[j],则新的交集等于“阴影w+ P[i]”,交集的长度Next[i+1] = Next[i]+1。
在这里插入图片描述
2)若P[i] ≠ P[j],说明后缀的“阴影w+P[i]”与前缀的“阴影w+P[j]”不匹配,只能缩小范围找新的交集。

在这里插入图片描述

下图合并了前缀和后缀,画出完整的子串P[0]~P[i],最后的字符P[i]和P[j]不等。
在这里插入图片描述
在这里插入图片描述
把前缀往后滑动,也就是通过减小j来缩小前缀的范围,直到找到一个匹配的P[i] = P[j]为止。
如何减小j?只能在w上继续找最大交集,这个新的最大交集是Next[j],所以更新j’ = Next[j]。
下图斜线阴影v是w上的最大交集,下一步判断:

若P[i] = P[j’],则Next[i+1]等于v的长度加1,即Next[j’]+1;
若P[i] ≠ P[j’],继续更新j’。

在这里插入图片描述
10. KMP算法代码如下!!!

N=1000005
Next = [0]*N
def getNext(p):                      #计算Next[1]~Next[plen]
    for i in range(1,len(p)):
        j = Next[i];                 #j的后移:j指向前缀阴影w的后一个字符
        while j>0 and p[i] != p[j]:  #阴影的后一个字符不相同
            j = Next[j]              #更新j
        if p[i]==p[j]:   Next[i+1] = j+1
        else:             Next[i+1] = 0
def kmp(s,p):
    ans = 0
    j = 0
    for i in range(0,len(s)):        #S的i指针,它不回溯,用for循环一直往前走。
#匹配S和P的每个字符                             
        while j>0 and s[i]!=p[j]:    #失配了
             j=Next[j]               #j滑动到Next[j]位置
        if s[i]==p[j]:               #若s[i]==p[j],说明当前P的字符和S的字符匹配j++,
#同时回到13行i++
#下一步匹配s[i+1]和p[j+1]。
#当前位置的字符匹配,继续
            j+=1
            ans = max(ans,j)          
        if j == len(p): return ans   #最长前缀就是p的长度,直接返回                       
    return ans                       #返回p在s中出现的最长前缀
s=input()
t=input()  
getNext(t)
print(kmp(s,t))
  1. 本题用kmp算法实现如下!!!
#KMP算法实现
def find(x):
    j=0
    for i in range(len(x)):
        while j!=0 and s[j]!=x[i]:
            j=p[j]
        if s[j]==x[i]:
            j=j+1
        if j==len(s):
            return 1
    return -1
s=input().strip()
m=int(input())
n=int(input())
if m==0:
    s=s.upper()
#计算kmp算法的next数组,这里我叫p
p=[0 for _ in range(len(s)+1)]
p[1]=0
j=0
for i in range(1,len(s)):
    while j != 0 and s[j] != s[i]:
        j = p[j]
    if s[j] == s[i]:
        j = j + 1
    p[i]=j
for i in range(n):
    x=input().strip()
    #枚举每一个母串,一次扫描
    if m==1:
        if find(x)!=-1:
            print(x)
    else:
        if find(x.upper())!=-1:
            print(x)

总结

程序员节快乐!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1126459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

进程之操作系统的概念

再小的努力&#xff0c;乘以365都很明显。文章目录 操作系统操作系统的概念设计操作系统的目的 管理 ps:如何理解管理如何进行管理 操作系统管理软硬件资源小总结系统调用和库函数的概念小总结 操作系统 在讲述进程的时候我们先讲述一下操作系统&#xff08;os&#xff09;,因…

基于Java的小说下载网站管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

支持多用户协作的API测试工具:Apipost

在当今快速发展的数字化时代&#xff0c;API已成为企业与开发者实现数据互通、应用集成的重要桥梁。然而&#xff0c;随着API数量的不断增加&#xff0c;API开发、调试、测试、文档等工作也变得越来越复杂。为了解决这一痛点&#xff0c;一款名为Apipost的API协同研发工具应运而…

Python基础入门例程6-NP6 牛牛的小数输出

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解答&#xff1a; 说明&#xff1a; 描述 牛牛正在学习Python的输出&#xff0c;他想要使用print函数控制小数的位数&#xff0c;你能帮助它把所有读入的数据都保留两位小数输出吗&#xff1f; 输入描述&a…

006:vue使用lottie-web实现web动画

文章目录 1. 简介2. 优点3. 效果4. 安装使用5. lottie-web 常用方法6. Lottie-web 常用的事件 1. 简介 官方介绍&#xff1a;Lottie 是一个库&#xff0c;可以解析使用AE制作的动画&#xff08;需要用bodymovie导出为json格式&#xff09;,支持web、ios、android、flutter和re…

LeetCode 22. 括号生成【字符串,回溯;动态规划】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

基于Java的线上花店管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

OJ题之反转链表

hello ~~~每日一练的分享来了。 今天up主将为大家分享一个 OJ题之反转链表 题目&#xff1a;将链表实现如下的变化 1.思路的讲解&#xff1a;对于原链表我们只需改变指针的指向&#xff08;箭头&#xff09;即可 那么问题就来了&#xff0c;我们如何实现此操作&#xff1f;…

Redis设计与实现(2)链表和链表节点

每一个链表节点 typedef struct listNode{//前置节点struct listNode *prev;//后置节点struct listNode *next;//节点值void *value }lisNode; 多个listNode可以通过pre和next指针组成双端链表 虽然只要使用多个listNode结构就可以组成链表&#xff0c;但使用adlist.h/list来…

NLP入门——语言结构/语言建模

一、Linguistics 语言学 wordsmorphology 形态学&#xff1a;词的构成和内部结构研究。如英语的dog、dogs和dog-catcher有相当的关系morpheme 语素&#xff1a;最小的语法单位&#xff0c;是最小的音义结合体lexeme 词位&#xff1a;词的意义的基本抽象单位&#xff0c;是一组…

C语言_字符串和内存函数

文章目录 前言一. strlen二. strcpy三.strcat四. strcmp &#xff08;字符串比较&#xff09;五. strncpy六. strncmp七. strstr八. strtok九 . strerror perror十. 字符分类函数十一. memcpy (内存拷贝&#xff09;十二. memmove(可以重叠拷贝 也可以实现不重叠的内存拷贝) 前…

CentOS7安装部署CDH6.2.1

文章目录 CentOS7安装部署CDH6.2.1一、前言1.简介2.架构3.环境 二、环境准备1.部署服务器2.安装包准备3.修改机器名4.关闭防火墙5.关闭 SELinux6.Hosts文件7.limits文件8.设置swap空间9.关闭透明巨页内存10.免密登录 三、安装CM管理端1.安装第三方依赖包2.安装Oracle的JDK3.安装…

Rockchip RK3399 - DRM crtc基础知识

一、LCD硬件原理 1.1 CRT介绍 CRT是阴极射线管(Cathode Ray Tube)的缩写&#xff0c;它是一种使用电子束在荧光屏上创建图像的显示设备。CRT显示器在过去很长一段时间内是主流的显示技术&#xff0c;现已被液晶显示屏或其他新兴技术所替代。 在CRT显示器中&#xff0c;扫描电子…

k8s-----6、pod的镜像拉取、重启策略、资源限制

镜像拉取、重启策略、资源限制 1、镜像拉取2、资源限制3、重启机制 1、镜像拉取 [rootmaster ~]# cat nginx.yaml apiVersion: v1 kind: Pod metadata:name: mypod spec:containers:- name: nginximage: nginx:1.14imagePullPolicy: Always# IfNotPresent: 默认值&#xff0c…

CPO是啥?

CPO是啥&#xff1f; CPO通常是“Chief Product Officer”&#xff08;首席产品官&#xff09;的缩写&#xff0c;是企业高层管理团队中负责产品管理和战略规划的主要负责人。CPO通常负责制定公司的产品战略、管理产品组合、带领产品团队以及推动产品的创新和优化。他或她需要有…

引用类型的按值传递

按值传递时&#xff0c;传递过去的是该引用类型实例的引用的一个拷贝&#xff0c;这样说可能不是很清楚&#xff0c;而且容易引起误解。所谓引用&#xff0c;就是分配在栈上的一小块内存区域&#xff0c;里面存放着该引用类型实例在托管堆上的地址。引用类型在按值传递的时候&a…

CUDA学习笔记(十三) Shared Memory

CUDA SHARED MEMORY shared memory在之前的博文有些介绍&#xff0c;这部分会专门讲解其内容。在global Memory部分&#xff0c;数据对齐和连续是很重要的话题&#xff0c;当使用L1的时候&#xff0c;对齐问题可以忽略&#xff0c;但是非连续的获取内存依然会降低性能。依赖于…

codeshell安装配置

codeshell安装配置 1 注意事项1.1 Python版本问题 2 codeshell环境搭建2.1 codeshell使用软件各版本2.2 软件下载2.3 codeshell使用环境安装2.3.1 python-3.10.9-amd64.exe安装2.3.2 Anaconda3-2022.10-Windows-x86_64.exe安装2.3.3 创建环境2.3.4 Pytorch安装2.3.5 transforme…

C++中的多态以及如何实现多态(近万字图文详解)

C中的多态 1. 多态的概念1.1 概念 2. 多态的定义及实现2.1多态的构成条件&#xff08;重点&#xff09;2.2 虚函数2.3 虚函数的重写(重点)2.4 C11 override 和 final2.5 重载、覆盖(重写)、隐藏(重定义)的对比 3. 抽象类3.1 概念3.2 接口继承和实现继承 4. 多态的原理4.1虚函数…

MySQL1——喵喵期末不挂科

宝宝&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重要…