您的位置:首页 > 其它

求一个字符串中最长的非重复连续子串

2010-06-10 10:31 447 查看
如abcadacef

最长的非重复子串为dacef. maxLen = 5

最直接的方法是O(n^2)解决,匹配所有子串

改进一

#include <stdio.h>
#include <stdlib.h>
#include <memory>
#define MAX 100

int flag[26];

void  getSub(char *str)
{
memset(flag, -1, sizeof(flag));
int tmpLen = 0;
int begin = 0;//上一个子串的起始位置
int max = 0;//最长非重复子串的长度
int res_b;//最长非重复子串的起点

for(int i = 0; str[i] != '/0'; i++)
{
int key = str[i] - 'a';
if(flag[key] == -1) //如果当前字符从未出现过,
{
tmpLen++;
flag[key] = i;
}
else
{
if(tmpLen > max)//如果当前的子串长度大于max
{
max = tmpLen;
res_b = begin;
}
int j;
for(j = begin; j < i; j++)//修正flag[]值
{
if(str[j] == str[i])
{
flag[key] = i;
break;
}
else
{
flag[str[j]-'a'] = -1;
}
}
begin = j + 1;
tmpLen = i - j;
}
}
if(tmpLen > max)
{
max = tmpLen;
res_b = begin;
}
//输出最长的子串结果
printf("max = %d/n", max);
for(int i=0; i < max; i++)
printf("%c", str[i + res_b]);
}

int main()
{
char s[MAX];
scanf("%s", s);
getSub(s);
system("pause");
return 0;
}


改进二,算法复杂度提高到O(n)

#include <stdio.h>
#include <stdlib.h>
#include <memory>
#define MAX 100

int flag[26];

void  getSub(char *str)
{
memset(flag, -1, sizeof(flag));
int tmpLen = 0;
int begin = 0;
int max = 0;//最长非重复子串的长度
int res_b;//最长非重复子串的起点

for(int i = 0; str[i] != '/0'; i++)
{
int key = str[i] - 'a';
if(flag[key] < begin) //如果当前字符在当前扫描子串未出现过
{
tmpLen++;
flag[key] = i;
}
else
{
if(tmpLen > max)//如果当前的子串长度大于max
{
max = tmpLen;
res_b = begin;
}
int j;
begin = flag[key] + 1;//当前子串应该从flag[key]+1开始重新计算
flag[key] = i;
tmpLen = i - begin + 1;//当前无重复子串的长度为tmpLen
}
}
if(tmpLen > max)
{
max = tmpLen;
res_b = begin;
}
//输出最长的子串结果
printf("max = %d/n", max);
for(int i=0; i < max; i++)
printf("%c", str[i + res_b]);
}

int main()
{
char s[MAX];
while(scanf("%s", s)!=EOF)
{
getSub(s);
printf("/n");
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐