文章目录
- 前言
- 一、题目
- 二、力扣官方解释
- 1、枚举
- 2、字符串匹配
- 三、文心一言解释
- 1、枚举
- 2、字符串匹配
- 总结
前言
刚上研一,有人劝我好好学C++,当时用的不多就没学,现在毕业上班了。在此亡羊补牢了
在此感谢力扣和文心一言
一、题目
给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
二、力扣官方解释
1、枚举
class Solution {
public:
bool repeatedSubstringPattern(string s) {
int n = s.size();
for (int i = 1; i * 2 <= n; ++i) {
if (n % i == 0) {
bool match = true;
for (int j = i; j < n; ++j) {
if (s[j] != s[j - i]) {
match = false;
break;
}
}
if (match) {
return true;
}
}
}
return false;
}
};
2、字符串匹配
public:
bool repeatedSubstringPattern(string s) {
return (s + s).find(s, 1) != s.size();
}
};
三、文心一言解释
1、枚举
int n = s.size();:获取字符串s的长度,并存储在变量n中。
for (int i = 1; i * 2 <= n; ++i) {:这是一个循环,用于尝试所有可能的子串长度。这里,i从1开始,并且每次增加1,直到i的两倍超过n为止。这是因为,如果子串长度为i,那么它至少需要重复两次才能构成整个字符串,所以i * 2必须小于或等于n。
if (n % i == 0) {:这个条件检查n是否可以被i整除。如果不可以,那么长度为i的子串不可能重复构成整个字符串s,因此可以跳过当前的i值。
在if条件块内部,bool match = true;初始化一个标志变量match,用于跟踪是否找到了匹配的重复子串。
for (int j = i; j < n; ++j) {:这是一个内层循环,用于比较子串的每一个字符是否都匹配。这里,j从i开始,因为子串的第一个字符与字符串s的第i个字符对应。
if (s[j] != s[j - i]) {:这个条件检查当前字符s[j]是否不等于它应该匹配的字符s[j - i]。如果不相等,那么match被设置为false,并且跳出内层循环。
if (match) { return true; }:如果match仍然是true(即没有在任何地方发现不匹配的字符),那么方法返回true,表示找到了一个可以重复构成整个字符串的子串。
如果循环结束后没有找到匹配的重复子串,方法返回false。
2、字符串匹配
return (s + s).find(s, 1) != s.size()
s + s:首先,将字符串s与自身拼接,得到一个新的字符串,其长度是s的两倍。
.find(s, 1):然后,在拼接后的字符串中从索引1(即第二个字符)开始搜索原始字符串s。find函数返回找到的子串的起始索引。如果s是一个重复子串,那么它会在拼接后的字符串中从第二个位置开始再次出现。
!= s.size():如果find函数返回的值不等于s.size(),说明在拼接后的字符串中找到了s,并且这个s不是从拼接字符串的起始位置开始的(因为起始位置搜索是从索引1开始的)。这就表明s是由某个子串重复构成的。
如果s不是由某个子串重复构成的,那么find函数将返回string::npos(通常是最大的可能size_t值),这将导致比较结果为true(因为string::npos肯定不等于s.size()),但函数实际上应该返回false。然而,这里的逻辑是反过来的:如果find返回的不是s.size(),函数返回true;否则(即find返回string::npos),由于比较失败,函数将隐式返回false。因此,这个函数实际上正确地实现了所需的功能。
`
总结
早学早烧脑,晚学来后悔