当前位置:首页 » 《资源分享》 » 正文

CSP 2022 提高级第一轮 CSP-S 2022初试题 程序阅读第一题解析

3 人参与  2024年09月19日 17:21  分类 : 《资源分享》  评论

点击全文阅读


二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填√,错误填×;除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分) 

一、代码查看

​#include <iostream> #include <string> #include <vector> using namespace std;  int f(const string &s, const string &t) {     int n = s.length(), m = t.length();     vector<int> shift(128, m + 1);     int i, j;    for (j = 0; j < m; j++)        shift[t[j]] = m - j;    for (i = 0; i <= n - m; i += shift[s[i + m]]) {        j = 0;        while (j < m && s[i +j] == t[j]) j++;        if (j == m) return i;    }    return -1;}int main(){    string a, b;    cin >> a >> b;    cout << f(a, b) << endl;    return 0;}​

二、代码分析

从第18 ~ 22 行代码可以很明显得看出,该题的目的是从s字符串中找出第一个字串t的位置。

for (i = 0; i <= n - m; i += shift[s[i + m]]) {    j = 0;    while (j < m && s[i +j] == t[j]) j++;    if (j == m) return i;}

j 是 t 串的下标,每次从 0 开始,和 s 串配对,发现不对结束内循环。最后判断 j 是否停留在  t 串的最后一个下标,如果是就说明找到了,便把 i 返回去。

理解了代码的大致意义后,我们从头开始看。

string a, b;cin >> a >> b;cout << f(a, b) << endl;

以上是 main() 函数中所做的,意义很简单,就是输入两个字符串 s, t,然后调用 f(s, t) 函数去找字串并输出结果。

接着我们看看 f(s, t) 函数中的内容。

int n = s.length(), m = t.length(); 

这句话将 s 串和 t 串的长度记录在两个变量里。

vector<int> shift(128, m + 1); for (j = 0; j < m; j++)    shift[t[j]] = m - j;

接下来是重点。shift容器中存的是跳过的步数。

3e7fba174fee47e8ab57d2c6bf89e6eb.png

第一次先访问s[0], 从0开始与 t 比较,如果对上了就返回,否则 i 要后移,但是后移几位就要看情况了。为了节省时间,我们要看看 s[i + m]。比如 t = “day”,这个时候我们看看s[i + m]是不是d、a、y中的一个,如果是d,那就从[3]开始,如果是a,那就从[2]开始,如果是y,就从下一个,也就是[1]开始,如果都不是,那就说明近3个不会出答案,那么就+4跳过。

这步看不懂评论区见

三、题目分析

判断题

1.(1 分)当输入为“abcde fg”时,输出为-1。(对)【因为abcde中找不到fg】

2.   当输入为“abbababbbab abab”时,输出为 4。(错)【因为字串abab起始位置从0开始,是3】

3.  当输入为“GoodLuckCsp2022 22”时,第 20 行的“j++”语句执行次数为 2。(错)【第一次++是第一个2后,第二次在第二个2后】

单选题

该算法最坏情况下的时间复杂度为(D)。

A. O(n + m)

B. O(n log m)

C. O(m log n)

D. O(nm)

【外循环n内循环m,所以n * m】

f(a, b) 与下列(A)语句的功能最类似

A. a.find(b)

B. a.rfind(b)
C. a.substr(b)
D. a.compare(b)

【.find()函数用于找字串,必须知道,写代码】

当输入为“baaabaaabaaabaaaa aaaa”,第 20 行的“j++”语句执行次数为 (B)。

A. 9

B. 10
C. 11
D. 12

【第一次s[0] = 'b',直接跳过,s[i + 5] = 'a',s[5]~s[7]执行了3次,s[5 + 4] = 'a',执行3次,s[9 + 4] = 'a',执行4次,共10次。

baaabaaabaaabaaaa 标记+过的下标都执行了一次j++

          +++  +++ ++++

看不懂评论区见,大家一起解答,有问题请反应~


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/161853.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1