さいちょうくりかえしさぶれつもんだい
8184 ワード
今日の面接は見たことのない問題に、すっかり退屈になった.1段の文字列の最も長い繰り返しのサブ列を求めます.後でネット上でブログを見て、意外にもKMPで書くことができて、自分の無知のために恥ずかしいと感じます.では、KMPでこのような問題を解決する方法を学びましょう.肝心なのはnextの特性でこの問題を解決することです.
KMPの特性を使ってこの問題を解決するには、時間の複雑さが少し高いでしょう.
物事にはいつも解決策があるので,接尾辞配列というデータ構造がこの方法を解決する.1つの文字列に対して対応する接尾辞配列を生成した後、並べ替え、並べ替えた後、隣接する2つの文字列の先頭部分を順次検出します.
#include <iostream>
#include <cstring>
using namespace std;
int Get_next(char *p, int nextval[])
{
int j = -1;
nextval[0] = -1;
int len = strlen(p);
int i = 0;
int maxlen = 0;
while(i < len)
{
if(j == -1 || p[i] == p[j])
{
i++;
j++;
nextval[i] = j;
if(j > maxlen) // ,
maxlen = j;
}
else
j = nextval[j];
}
return maxlen;
}
int main()
{
char s[100];
cin >> s;
int maxlen = 0;//
int nextMax; //Get_next
int i;
int maxIndex;
int len = strlen(s);
for(i = 0; i < len-1; i++)
{
int *next = new int[len - i];
nextMax = Get_next(s + i, next);
if(nextMax > maxlen)
{
maxIndex = i;
maxlen = nextMax;
}
}
cout << " :" << endl;
for(i = 0; i < maxlen; i++)
cout << s[i + maxIndex];
cout << endl;
}
KMPの特性を使ってこの問題を解決するには、時間の複雑さが少し高いでしょう.
物事にはいつも解決策があるので,接尾辞配列というデータ構造がこの方法を解決する.1つの文字列に対して対応する接尾辞配列を生成した後、並べ替え、並べ替えた後、隣接する2つの文字列の先頭部分を順次検出します.
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAXLEN 10000
char str[MAXLEN], *arr[MAXLEN];
int CalLen(const char *str1, const char *str2)
{
int len = 0;
while(*str1 && (*str1++ == *str2++))
len++;
return len;
}
int pStrCmp(const void *str1, const void *str2)
{
return strcmp(*(const char **)str1, *(const char **)str2);
}
int main()
{
char ch;
int n = 0;
int maxlen = 0, maxIndex = 0;
int temp;
while((ch = getchar()) != '
')
{
arr[n] = &str[n];
str[n++] = ch;
}
str[n] = '\0';
qsort(arr, n, sizeof(char *), pStrCmp);
for(int i = 0; i < n - 1; i++)
{
temp = CalLen(arr[i], arr[i + 1]);
if(temp > maxlen)
{
maxlen = temp;
maxIndex = i;
}
}
cout << arr[maxIndex] << endl;;
}