思路:

  1. 如果字符串长度为1,显然不能重复多次构成。
  2. 如果字符串长度大于1,那么最多可以重复多少次呢?假设字符串可以由子串s'重复k次构成,那么s的长度应该为k * s'的长度。因此,k = s.length() / s'.length()。如果k为0,则s'长度比s长,显然不可能由s'构成;如果k为1,则s'就是s本身,也不需要重复;否则,我们需要检查s是否由k个s'构成,即判断s是否等于k * s'。
  3. 如何判断s是否等于k * s'呢?我们可以使用KMP算法,先在s中匹配s',然后在s中从s'.length()开始匹配s',直到匹配k次为止,看最后剩下的字符串是否为空。

代码实现:

#include <iostream>
#include <vector>
using namespace std;

// KMP算法
vector<int> get_next(string& pattern) {
    int n = pattern.length();
    vector<int> next(n, 0);
    int i = 1, j = 0;
    while (i < n) {
        if (pattern[i] == pattern[j]) {
            next[i] = j + 1;
            i++;
            j++;
        } else if (j > 0) {
            j = next[j - 1];
        } else {
            i++;
        }
    }
    return next;
}

// 判断s是否可以由一个子串重复多次构成
bool repeatedSubstringPattern(string s) {
    int n = s.length();
    if (n == 1) {
        return false;
    }
    for (int len = 1; len <= n / 2; len++) {
        if (n % len == 0) {
            int k = n / len;
            string pattern = s.substr(0, len);
            vector<int> next = get_next(pattern);
            int i = len, j = 0;
            while (i < n && j < len && s[i] == pattern[j]) {
                i++;
                j++;
            }
            if (j == len) {
                j = next[len - 1];
            }
            for (int t = 2; t <= k; t++) {
                while (j < len && s[i] == pattern[j]) {
                    i++;
                    j++;
                }
                if (j != len) {
                    break;
                }
                j = next[len - 1];
            }
            if (i == n && j == 0) {
                return true;
            }
        }
    }
    return false;
}

// 测试
int main() {
    cout << repeatedSubstringPattern("abab") << endl; // true
    cout << repeatedSubstringPattern("aba") << endl; // false
    cout << repeatedSubstringPattern("abcabcabcabc") << endl; // true
    cout << repeatedSubstringPattern("a") << endl; // false
    cout << repeatedSubstringPattern("aa") << endl; // true
    return 0;
}

原文地址: http://www.cveoy.top/t/topic/bnj1 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录