top1编程
← 返回题目
题解

验证子串

1 条题解

  • 0
    @ 2026-8-5 10:18:17

    解题思路

    要判断第二个字符串 b 是不是第一个字符串 a 的子串,也就是 a 里有没有"连续的一段"和 b 完全一样。

    思路:枚举 b 在 a 中的起始位置。

    1. 起点 i 可以是 0, 1, ..., n-m(n 是 a 的长度,m 是 b 的长度),因为从 i 开始至少要剩下 m 个字符才够比。
    2. 对每个起点 i,用 a.substr(i, m) 取出 a 从 i 开始、长度为 m 的那一段,和 b 比较。
    3. 只要有一个位置相等,就输出 YES;全部位置都不等,就输出 NO。

    注意:第一行字符串可能包含空格(比如 Hello everyone),所以要使用 getline 读一整行。

    举例:a = "Hello everyone",b = "one"。在 everyone 里从第 5 个字符开始正好是 one,匹配成功,所以输出 YES。

    参考代码

    // 验证子串:判断第二个字符串是否为第一个字符串的子串
    #include <iostream>
    using namespace std;
    int main() {
        string a, b;         // a为长串,b为待验证的串
        getline(cin, a);     // 第一行可能含空格,用getline读整行
        getline(cin, b);
        int n = a.size(), m = b.size();
        bool ok = false;     // 标记是否为子串
        for (int i = 0; i + m <= n && !ok; i++) // 枚举b在a中的起始位置
            if (a.substr(i, m) == b) ok = true; // 从i起长度m这一段等于b
        cout << (ok ? "YES" : "NO") << endl;
        return 0;
    }
    

    复杂度分析

    两个字符串长度都不超过 20。最坏情况下有 n-m+1 个起点,每个起点要比较 m 个字符,时间复杂度为 O(n·m)。因为 n、m 都很小(不超过 20),运行非常快。空间上 substr 每次临时取出一段,长度不超过 m,总体约 O(n)。

    • 1