求串的第一个最长重复子串的下标和长度

/*
采用顺序结构存储串,编写一个程序,求串s中出现的第一个最长重复子串的下标和长度。


1.读取串
2.求后缀数组
3.字典序排序所有后缀
4.求相邻后缀最长子串
5.比较本次结果与上次结果,取最大
*/


#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<fstream>


using namespace std;


typedef vector<string>::iterator ITER;//从定义类型


class max_substr
{
public:
max_substr(){}


~max_substr(){}

//文件读入串
void getstr(string name)
{
ifstream readfile;
readfile.open(name, ios::in);
if (readfile.is_open())//是否打开
{
getline(readfile, s);//读取一行
cout << s << endl;
}
readfile.close();
}


void solve()
{
int temp, max;
string t, max_t;


//得到后缀数组
for (size_t i = 0; i<s.size(); ++i)
{
t = s.substr(i, s.size());//求后缀
behind.push_back(t);
rank.insert(pair<string, int>(t, i));//存储后缀及其首字符下标
}
stable_sort(behind.begin(), behind.end());//按字典序排序,默认为从小到大
max = -1;
//迭代比较相邻两后缀
for (iter = behind.begin(); *iter != behind.back(); ++iter)
{
temp = MaxPrefix(iter, iter + 1);//取最长子串尾字符下标
if (temp>max)//与前一个比较,取最长
{
max = temp;
max_i = iter;
}
}


for (int i = 0; i<max; ++i)//取出重复串
max_t += (*max_i)[i];
cout << "长度为:" << max << endl;
cout << "下标为:" << rank[max_t] << endl;
cout << max_t << endl;
}


private:
string s;
vector<string> behind;//后缀数组
map<string, int> rank;//关联容器
ITER iter, max_i;//迭代/保存字符地址位置


//得到相邻两串最长公共字符子串尾下标
int MaxPrefix(ITER s1, ITER s2)
{
int i = 0;
while (!(*s1).empty() && (*s1)[i] == (*s2)[i])//当前字符相等比较下一位
{
++i;
}
return i;
}
};


int main()
{
max_substr str;
str.getstr("data");
str.solve();
return 0;
}


测试结果



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值