一天,小明学习到了字符串的相关知识。为了巩固知识,他在网上找到了这样一个题目:给定n(n<=10)个字符串环,每个字符串的长度为m(m<=500),保证每个字符串中只有小写字母,求出每个字符串环有多少个本质不同的子串(两个字符串不相同则认为本质不同)。求解本质不同的子串是一个经典的问题,师生提出了三种效率不同的做法,最简单但是最慢的方法老师不屑于去讲,当然你也可以使用字典树来记录所有的子串,时间复杂度O(m^2),如果你也想像大佬一样厉害,也可以学习后缀自动机来求解该问题,时间复杂度O(m)。如果你可以使用效率较高的程序来解决这个问题,就更好了!
输入
一共有n+1行输入
第一行输入n,表示测试实例的个数
接下来的n行,每行包括一个测试实例
输出
对于每个测试实例,输出该字符串环中本质不同的子串个数,每个输出占一行。
样例输入
2
3个a(敏感字符,所以这么表达)
abc
样例输出
3
9
提示:
字符串环是指一种形成环的字符串,例如abc,字符a后面跟着b,b后面跟着c,c后面跟着a。箭头方向由a指向b,由b指向c,由c指向a。
对于第一个测试实例(三个a),它有一个a,两个a,三个a,具有三个本质不同的子串。
对于第二个测试实例abc,它有a,b,c,ab,bc,ca,abc,bca,cab九个本质不同的子串。
代码如下,望采纳,有问题再交流处理,谢谢
#include <iostream>
#include <string>
#include <set>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
string str;
cin >> str;
str += str; // 将字符串复制一份,形成环
// 使用 set 来去重,因为 set 自动去重
set<string> s;
for (int j = 0; j < str.size(); j++) {
for (int k = 1; k <= str.size() / 2; k++) {
// 从第 j 个字符开始,截取长度为 k 的字符串
s.insert(str.substr(j, k));
}
}
// 输出 set 中的元素个数,即为答案
cout << s.size() << endl;
}
return 0;
}