CSP-S 2022 提高级 第一轮 阅读程序(1) 第16-21题

news2024/11/25 16:51:26

【题目】

CSP-S 2022 提高级 第一轮 阅读程序(1) 第16-21题

01 #include <iostream> 
02 #include <string> 
03 #include <vector> 
04 
05 using namespace std; 
06 
07 int f(const string &s, const string &t) 
08 { 
09     int n = s.length(), m = t.length(); 
10 
11     vector<int> shift(128, m + 1);
12 
13     int i, j;
14 
15     for (j = 0; j < m; j++) 
16         shift[t[j]] = m - j; 
17 
18     for (i = 0; i <= n - m; i += shift[s[i + m]]) { 
19         j = 0; 
20         while (j < m && s[i + j] == t[j]) j++; 
21         if (j == m) return i;
22     }
23 
24     return -1; 
25 } 
26 
27 int main() 
28 { 
29     string a, b;
30     cin >> a >> b;
31     cout << f(a, b) << endl;
32     return 0;
33 }

假设输入字符串由 ASCII 可见字符组成,完成下面的判断题和单选题:
判断题
16. 当输入为“abcde fg”时,输出为-1。( )
17. 当输入为“abbababbbab abab”时,输出为 4。( )
18. 当输入为“GoodLuckCsp2022 22”时,第 20 行的“j++”语句执行次数为 2。( )

单选题
19. 该算法最坏情况下的时间复杂度为( )。
A. O(n+m) B. O(n log m) C. O(m log n) D. O(nm)
20. f(a, b)与下列( )语句的功能最类似。
A. a.find(b) B. a.rfind(b) C. a.substr(b) D. a.compare(b)
21. 当输入为“baaabaaabaaabaaaa aaaa”,第 20 行的“j++”语句执行次数为( )。
A. 9 B. 10 C. 11 D. 12

【题目考点】

1. 字符串

  • 字符串模式匹配

2. vector

vector初始化:
vector<元素类型> 对象名(元素个数,初始值)

例:
vector<int> v(10, 3);
生成一个vector<int>类型的对象v,其中包含10个元素,每个元素都是3。也就是说v.size()为10,v[0]~v[9]都是3。

【解题思路】

27 int main() 
28 { 
29     string a, b;
30     cin >> a >> b;
31     cout << f(a, b) << endl;
32     return 0;
33 }

先看主函数,输入两个字符串,由f函数处理,输出函数返回的一个什么值。

07 int f(const string &s, const string &t) 
08 { 
09     int n = s.length(), m = t.length(); 
10 
11     vector<int> shift(128, m + 1);

再看函数f,传入两个字符串s,t,先求出字符串长度。s的长度是n,t的长度是m。
而后声明了一个vector,名字叫shift。shift这个词除了由“上档键”的意思,还有“转移,移位”的意思。(其实根据单词可以判断出很多信息,各位同学平时要注意多学习英文单词。)
shift后面的括号中传入两个参数,这是使用了vector的构造函数,传入的第1个参数表明初始化元素的个数,第二个参数是每个元素的值。也就是说,声明出来的shift的长度(元素个数)shift.size()为128,这128个元素,即shift[0]~shift[127]的值都是m+1。至于这个shift是做什么用的,接着往下看。

13     int i, j;
14 
15     for (j = 0; j < m; j++) 
16         shift[t[j]] = m - j; 

t[j]是字符,作为shift的下标,也就是以字符的ASCII码为下标,这也对应了shift中要有128个元素。shift的t[j]位置要赋值为m-j,暂时无法理解。如果无法理解就继续向下看,不要纠结于一处,要大处着眼。

18     for (i = 0; i <= n - m; i += shift[s[i + m]]) { 
19         j = 0; 
20         while (j < m && s[i + j] == t[j]) j++; 
21         if (j == m) return i;
22     }
23 
24     return -1; 

先看for循环,i从0到n-m,i每次增加shift[s[i + m]]这么一个东西,看不出是什么。
再看循环内部,j从0循环到m-1,每次判断s[i+j]t[j]是否相等。如果看到有不相等的字符,就跳出。如果j遍历到最后,j已经为m,就返回i。
大家应该能看出这一段在做什么(否则就要反思一下自己字符串一节学得如何)这里就是在判断字符串s[i]~s[i+m-1]与字符串t是否相同。如果相同,则返回i。
结合for循环,i从0到n-m,不断比较s[i]~s[i+m-1]与字符串t是否相同,最后一次比较的就应该是s[n-m]~s[n-1]是否与t相同。如果i每次增加1,这就是我们熟悉的判断一个字符串在另一个字符串中出现的位置的代码,也叫字符串的模式匹配。最后的return -1意味着在s中没有找到t,t不是s的子串。
而i每次增加的不是1,而是shift[s[i + m]],显然应该是进行了某种优化。每次i增加1复杂度太高了,可以多加一些,减少循环次数。
在这里插入图片描述

结合上面的shift[t[j]] = m-j,以及for循环中的增量表达式i += shift[s[i + m]],i每次增加的量是由s[i+m]决定的。

  • 如果s[i+m]不是t中的字符,那么接下来看的s的子串中只要包含s[i+m],s中的子串与t就一定不能相同(不能匹配)。因此i应该增加m+1,下一次循环从i+m+1开始,看m个字符,看是否与t相同。这也是vector<int> shift(128, m + 1)将shift中元素的初值设为m+1的原因。
  • 如果s[i+m]是t中的字符,那么应该让s[i+m]与t中最后一个该字符对齐,接下来看能否匹配。
    在这里插入图片描述

s[i+m]为c,字符串t中最后一个字符c出现的下标为j,那么当t[j]s[i+m]对应时,t[0]s[i+m-j]对应,也就是说i应该增加m-j。
再结合

15     for (j = 0; j < m; j++) 
16         shift[t[j]] = m - j; 

以及i += shift[s[i + m]]
可知shift[c]表示当s[i+m]为c时,为了进行下一次有效的匹配,i应该增加的量。
如果t[j]在字符串中重复出现,j更大时shift[t[j]]的值会更新,即shift[c]保存的是字符串t中最后一个c与s[i+m]对应时,i应该增加的量。

整个程序就是优化后的字符串模式匹配,输入字符串a, b

  • 如果b是a的子串,输出b在a中第一次出现的位置
  • 如果b不是a的子串,输出-1。

判断题

16. 当输入为“abcde fg”时,输出为-1。( )
答:T。
fg不是abcde的子串,输出-1,正确。
17. 当输入为“abbababbbab abab”时,输出为 4。( )
答:F。
abab在abbababbbab中第一次出现的位置为3,不是4。错误。
18. 当输入为“GoodLuckCsp2022 22”时,第 20 行的“j++”语句执行次数为 2。( )
答:T。
遍历到Csp2022的22时,会满足条件,执行两次j++后,j==m,直接跳出,返回结果。

单选题

19. 该算法最坏情况下的时间复杂度为( )。
A. O(n+m) B. O(n log m) C. O(m log n) D. O(nm)

答:选D。
比如s是"aaaaaaaa",t是”bbbba”,那么shift['a']为1,i每次增加1,都不能匹配。整体复杂度会退化成没有优化的基本字符串模式匹配。每次匹配都要循环近m词,共进行(n-m)m次,当n >= m时, O ( ( n − m ) m ) = O ( n m ) O((n-m)m) = O(nm) O((nm)m)=O(nm)

20. f(a, b)与下列( )语句的功能最类似。
A. a.find(b) B. a.rfind(b) C. a.substr(b) D. a.compare(b)

答:选A。
f函数实现了字符串查找,如果b不是a的子串则返回-1。
string类的成员函数find也实现了相同的功能。
21. 当输入为“baaabaaabaaabaaaa aaaa”,第 20 行的“j++”语句执行次数为( )。
A. 9 B. 10 C. 11 D. 12

答:选B
手动运行,在纸上执行程序。
shift['a']为1。
i为0,baaa中的第一个b与aaaa中的第1个a不同,直接跳过。此时s[i+m]是b,shift['b']为m+1,i直接增加m+1,也就是5。
i为5,指向第2组baaa中的第1个a。匹配3个a,j++执行3次,遇到b与a不相等。此时s[i+m]是a,shift['a']为1,i增加1。
i为6,指向第2组baaa中的第2个a。匹配2个a,j++执行2次,遇到b与a不相等。此时s[i+m]是a,shift['a']为1,i增加1。
i为7,指向第2组baaa中的第3个a。匹配1个a,j++执行1次,遇到b与a不相等。此时s[i+m]是a,shift['a']为1,i增加1。
i为8,指向第3组baaa中的第1个b。此时s[i+m]是b,shift['b']为m+1,i直接增加m+1,变为13。
i为13,执行字符串最后aaaa中的第1个a,与模式串aaaa匹配4个a,j++执行4次。
j++总计执行10次。

【答案】

  1. T
  2. F
  3. T
  4. D
  5. A
  6. B

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

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

相关文章

关于cartographer建立正确关系树的理解

正确的TF关系map----odom----base_link----laser base_link是固定在机器人本体上的坐标系&#xff0c;通常选择飞控 其中map–odom 的链接是由cartographer中lua文件配置完成的 map_frame "map", tracking_frame "base_link", published_frame "b…

Ubuntu 20.04 安装 mysql8 并配置远程访问

文章目录 一、使用 apt-get 安装 mysql 服务二、初始化 mysql 数据库管理员用户密码三、配置远程访问 一、使用 apt-get 安装 mysql 服务 # 更新软件源 apt-get install update# 安装mysql服务 apt-get install mysql-server# 使用mysqladmin工具查看mysql版本 mysqladmin --v…

一文解析Linux进程的睡眠和唤醒

Linux进程的睡眠和唤醒 在Linux中&#xff0c;仅等待CPU时间的进程称为就绪进程&#xff0c;它们被放置在一个运行队列中&#xff0c;一个就绪进程的状 态标志位为 TASK_RUNNING。一旦一个运行中的进程时间片用完&#xff0c; Linux 内核的调度器会剥夺这个进程对CPU的控制权&…

燃气巡检二维码

对燃气公司的输气管道和阀井等设施的巡检工作的管理目标是能降低成本、提高工作效率以及管理水平。但用纸质记录的方式进行燃气设备巡检有以下缺点&#xff1a; 1、难保证巡检真实性 无法客观、方便地掌握巡检人员巡检的到位情况&#xff0c;因而无法有效地保证巡检工作人员按计…

软件兼容性测试如何进行?怎么选择靠谱的软件检测公司?

软件兼容性测试是一项非常重要的工作&#xff0c;能够确保在不同的操作系统、设备、浏览器以及其他软件环境下&#xff0c;软件应用都能够正常运行。 一、软件兼容性测试如何进行? 确定测试的环境&#xff0c;包括操作系统、设备、浏览器等&#xff0c;并建立测试用例和测试…

Maven必要知识

参考笔记&#xff1a; https://www.wolai.com/arAiYJYCr6Kkfi2kZ8HxE8 1. Maven 概述 1.1 什么是 Maven Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。 Maven 作为依赖管理工具 jar 包的管理jar 包的来源jar 包之间的依赖关系…

使用R语言绘制折线图

R语言绘制折线图 一、绘制折线图1.载入bruceR&#xff08;ggplot2&#xff09;2.设置当前工作目录3.载入数据集4.查看数据结构5.绘制基础图形6.图形优化 二、绘制多重折线图1.载入数据2.绘制图形 一、绘制折线图 1.载入bruceR&#xff08;ggplot2&#xff09; &#xff08;要…

【HAL库】STM32CubeMX开发----非阻塞延时实验----SysTick(滴答定时器)中断

STM32CubeMX 下载和安装 详细教程 【HAL库】STM32CubeMX开发----STM32F103/F207/F407----目录 前言 HAL库 有自带的 ms级 延时函数&#xff1a; HAL_Delay(); 缺点&#xff1a; 这是阻塞延时方式&#xff0c;就是延时期间&#xff0c;什么都不能干&#xff0c;这样很浪费资源。…

便携式车用CAN分析仪

产品简介 USBCAN-C系列便携式车用CAN分析仪&#xff0c;通过USB接口快速扩展一路CAN通道&#xff0c;使接入CAN网络非常容易&#xff0c;它具有一体式和小巧紧凑的外形&#xff0c;特别适合于随身携带。CAN接口采用金升阳电源模块和信号隔离芯片实现2500V DC电气隔离&#xff0…

能源设备智能维修AR远程作业指导平台降低运营成本

AR远程专家指导系统是一种基于AR增强现实技术搭建的远程协作解决方案&#xff0c;它可以让专家全视角掌握操作现场&#xff0c;并将专精知识和技能传递给远程现场的工作人员&#xff0c;以帮助他们解决各种技术难题和困难&#xff0c;赋能各行各业行业。 现场人员通过手机、平板…

OJ练习第104题——格雷编码

格雷编码 力扣链接&#xff1a;89. 格雷编码 题目描述 n 位格雷码序列 是一个由 2n 个整数组成的序列&#xff0c;其中&#xff1a; 每个整数都在范围 [0, 2n - 1] 内&#xff08;含 0 和 2n - 1&#xff09; 第一个整数是 0 一个整数在序列中出现 不超过一次 每对 相邻 整数…

数据流图(DFD)这么理解吗?

如何画好数据流程图&#xff08;DFD&#xff09;&#xff1f; 步骤&#xff1a; 确定系统的 input 和 output。由 表层 到 深层 画系统的顶层数据流图。自顶向下 逐层 分解&#xff0c;画出分层数据流图。 一、理解数据流图 基本概念 ~~ 数据流图 数据流&#xff08;箭头&…

linux pinctrl 和 gpio 子系统 LED驱动

pinctrl 和 gpio 子系统 借助 pinctrl 和 gpio 子系统来简化 GPIO 驱动开发 pinctrl 子系统 pinctrl 子系统&#xff08;drivers/pinctrl&#xff09;的主要工作内容&#xff1a; ①、获取设备树中 pin 信息。 ②、根据获取到的 pin 信息来设置 pin 的复用功能 ③、根据获…

校招失败后,4面字节跳动软件测试工程师,竭尽全力....

下面是我面试字节跳动软件测试工程师的面试经验总结&#xff0c;希望能帮助到你们。 面试一 简单做一下自我介绍简要介绍一下项目/你负责的模块/选一个模块说一下你设计的用例get请求和post请求的区别如何判断前后端bug/3xx是什么意思说一下XXX项目中你做的接口测试/做了多少次…

免费润色文章的软件-自动修改文章润色的软件

免费润色文章的软件 免费润色文章的软件可以帮助用户快速地改善文本质量&#xff0c;进一步提高语言表达能力和流畅性&#xff0c;以下是其主要优势&#xff1a; 高效性&#xff1a;免费润色文章的软件能够快速进行润色处理&#xff0c;为用户节省时间和精力。相比手动润色的方…

瑞芯微RK3588核心板远程会诊等医学解决方案

RK3588处理器在医学领域的应用中&#xff0c;可以为远程会诊提供高性能和可靠的解决方案。以下是基于RK3588的远程会诊医学方面的解决方案&#xff1a; 远程高清图像传输&#xff1a; 利用RK3588处理器的高性能图像处理能力和高速网络接口&#xff0c;实现高清医学图像的实时传…

Dubbo 基于xml文件分析主流程源码 (4)

目录 前提 JDK实现SPI Dubbo实现SPI Dubbo源码 1. 找到Dubbo的命名空间处理类&#xff0c;也就是Dubbo的入口类 2. 将dubbo标签交给spring进行管理&#xff0c;就是从 BeanDefinition----> Bean的过程。 3. 服务暴露 4. 服务引入 总结 仿写Dubbo 前提 1. Dubbo源码…

CentOS7 yum update y更新后黑屏解决方案

解决方法 一 可以ssh访问 因为update的时候更新了系统内核&#xff0c;导致驱动问题&#xff0c;所以会黑屏。 更改一下yum的配置即可解决: vi /etc/yum.conf#增加&#xff1a;excludecentos-release*excludekernel*如果以上问题还未解决&#xff0c;可以试试下面的方法 其…

架构模式之分层模式

1 概念 分层架构模式是一种非常常见的架构设计模式&#xff0c;很多人都在用&#xff0c;可能不知道它的概念。分层模式背后的理念是&#xff0c;具有相同功能的组件将被组织成水平层。因此&#xff0c;每一层在应用程序中都扮演着特定的角色。 在这种模式中&#xff0c;…

自学自动化测试,第一份工作就18K,因为掌握了这些技术

我个人的情况是有1年自动化测试工作经验半年的实习经验&#xff0c;2020年毕业&#xff0c;专业通信工程&#xff0c;大一的时候学过C语言&#xff0c;所以一直对于编程感兴趣&#xff0c;之所以毕业后没做通信的工作&#xff0c;通信行业的朋友应该都明白&#xff0c;通信的天…