P8835 [传智杯 #3 决赛] 子串 ----- KMP算法、字符串匹配、字母大小写转换

题目背景

disangan233 喜欢字符串,于是 disangan333 想让你找一些 disangan233 喜欢的串。

题目描述

在传智的开发课堂上,希望您开发一款文档处理软件。

给定 TT 组询问,每次给定 22 个长度为 n,mn,m 的只含英文字母的字符串 a,ba,b,求 aa 在 bb 中的出现次数,相同字符不区分大小写。注意 aa 是 bb 中连续子序列。

对于所有数据,T\leq 100T100,\sum n\leq \sum m\leq 10^3nm103。字符串仅由大小或者小写的英文字母组成。

输入格式

输入共 3T+13T+1 行。

第 11 行输入 11 个正整数 TT。

接下来共 TT 组输入,每组输入共 33 行。

第 11 行输入 22 个正整数 n,mn,m。

第 22 行输入一个长度为 nn 的字符串 aa。

第 33 行输入一个长度为 mm 的字符串 bb。

输出格式

输出共 TT 行,第 ii 行输出 11 个整数,表示询问 ii 的答案。

输入输出样例

输入 #1
5
3 10
abc
abcabcabca
2 10
aa
AAaAaaAaAa
5 5
AbCdE
eDcBa
5 5
abcde
ABCDE
3 10
aba
ABaBaAbaBA
输出 #1
3
9
0
1
4
KMP 算法详解👉 P8195 [传智杯 #4 决赛] 小智的疑惑 ----- 字符串匹配、KMP算法优化next数组 - slowlydance2me - 博客园 (cnblogs.com)
#include <iostream>
#include<iomanip>
#include <math.h>
#include <vector>
#include <unordered_set>

using namespace std; 

vector<int> get_next(string a) {
    int n = a.size();
    vector<int> next;
    next.push_back(0);
    int left = 0, right = 1;
    while (right < n) {
        if (a[left] == a[right] || a[left] == a[right] - 32 || a[left] == a[right] + 32) {
            left++;
            right++;
            next.push_back(left);
        }
        else if (left) {
            left = next[left - 1];
        }
        else {
            next.push_back(0);
            right++;
        }
    }
    return next;
}

int main() {
    vector<int> resvec;
    int T ,n, m;
    cin >> T;
    while (T--) {
        int res = 0;
        string a, b;
        cin >> n >> m;
        cin >> a;
        cin >> b;
        vector<int> next = get_next(a);
        int i = 0, j = 0;
        while (i < m) {
            if (b[i] == a[j] || b[i] == a[j] - 32 || b[i] == a[j] + 32) {
                j++;
                i++;
            }
            else if(j) {
                j = next[j - 1];            
            }
            else {
                i++;
            }
            if (j == n) res++, j = next[j - 1];
        }
        cout << res << endl;
        //resvec.push_back(res);
    }
    //cout << resvec[0];
    //for (int i = 1; i < resvec.size(); ++i) cout << endl << resvec[i];
    return 0;
}

字母大小写转换三种方法:

  • +/- 32

  • 字符数组 strupr/strlwr

  • 对字符使用toupper、tolower / 利用transform和tolower及toupper进行结合

(17条消息) C++字母大小写转换方法_木顶思上的博客-CSDN博客_c++小写字母转大写字母

posted @ 2022-11-23 15:04  slowlydance2me  阅读(61)  评论(0编辑  收藏  举报