📌  相关文章
📜  字符串中子字符串的频率 c++ (1)

📅  最后修改于: 2023-12-03 15:39:02.123000             🧑  作者: Mango

字符串中子字符串的频率

在文本处理中,经常会涉及到对给定字符串中子字符串的频率进行计算的需求。本文将介绍如何使用C++语言实现对字符串中子字符串的频率计算。

1. 问题描述

给定一个字符串str和一个子字符串substr,要求计算子字符串在给定字符串中出现的次数。例如,如果给定字符串是"aaabbaa",子字符串是"aa",那么子字符串在给定字符串中出现的次数为2。

2. 解决方案
方法一:暴力枚举

最朴素的方法是从给定字符串的首字符开始,挨个比较该位置开始的子字符串和目标子字符串是否相同。如果相同,计数器加1,接着继续比较从下一个字符开始的子字符串,以此类推。该实现的时间复杂度为O(N*M),其中N是给定字符串的长度,M是子字符串的长度。

int countSubstr(string str, string substr) {
    int count = 0;
    for (int i = 0; i <= str.length() - substr.length(); i++) {
        bool isMatched = true;
        for (int j = 0; j < substr.length(); j++) {
            if (str[i+j] != substr[j]) {
                isMatched = false;
                break;
            }
        }
        if (isMatched) {
            count++;
        }
    }
    return count;
}
方法二:KMP算法

KMP算法是一种高效的字符串匹配算法,在这里,我们可以将其用于求子字符串的频率。该算法的时间复杂度为O(N+M),其中N是给定字符串的长度,M是子字符串的长度。相比于第一种方法,KMP算法的优势更加明显。

int countSubstr(string str, string substr) {
    int count = 0;
    int n = str.length(), m = substr.length();
    vector<int> next(m + 1, 0);
    for (int i = 1, j = 0; i < m; i++) {
        while (j && substr[i] != substr[j]) {
            j = next[j];
        }
        if (substr[i] == substr[j]) {
            j++;
        }
        next[i+1] = j;
    }
    for (int i = 0, j = 0; i < n; i++) {
        while (j && str[i] != substr[j]) {
            j = next[j];
        }
        if (str[i] == substr[j]) {
            j++;
        }
        if (j == m) {
            count++;
            j = next[j];
        }
    }
    return count;
}
3. 总结

本文介绍了两种方法来解决字符串中子字符串的频率计算问题。方法一是最朴素的暴力枚举,时间复杂度为O(N*M)。方法二是KMP算法,时间复杂度为O(N+M),相比之下更加高效。需要注意的是,KMP算法需要预处理出子字符串的next数组,这会增加一些额外的时间和空间开销。