回复 24楼 九转星河
试了一下,没细测。
/*
取字符串中不重复最长的子串
如:abcdab 取出 abcd、bcda、cdab
字符串...3212134532156....出现2重复
子串.....321..............下次从2后面的1开始
字符串...3212134532156....出现1重复
子串.......12.............下次从1后面的2开始
字符串...3212134532156....出现3重复
子串........21345.........下次从3后面的4开始
字符串...3212134532156....出现5重复
子串...........45321......下次从5后面的3开始
字符串...3212134532156....结束
子串.............32156
不重复最长子串
21345、45321、32156
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned long *_maxlist(char *s, int *count, int *maxlen)
{
if (!*s)
return NULL;
char *p;
char chr[256]={0};
int len=strlen(s);
int i, j, max;
unsigned long *maxlist=(unsigned long *)malloc(sizeof(unsigned long));
*maxlen = 0;
*count = 0;
i = 0;
while (i <= len-*maxlen)
{
j = i;
while (j<=len)
{
if (s[j] && (chr[(unsigned char)s[j]] == 0))
//不是重复字符
{
chr[(unsigned char)s[j]] = j-i+1;
//以序号为标记,出现重复时就从这个字符之后重新开始。
j++;
//继续下一个字符
}
else
//是重复字符
{
max = j-i;
//字串长度
if (max > *maxlen)
//是较长字串
{
*maxlen = max;
//保存较长值
*count = 1; //第一个较长的字串
maxlist = (unsigned long *)realloc(maxlist, sizeof(unsigned long)); //重建字串地址列表
maxlist[0] = (unsigned long)(s+j-max);
//保存字串地址
}
else if (max == *maxlen)
//是等长字串
{
*count += 1;
//增加一个字串
maxlist = (unsigned long *)realloc(maxlist, (*count)*sizeof(unsigned long));
maxlist[*count-1] = (unsigned long)(s+j-max);
}
if (s[j])
i += chr[(unsigned char)s[j]];
//下次搜索开始位置为子串中出现重复字符的后一位位置。
else
i++;
memset(chr, 0, 256);
break;
}
}
}
return maxlist;
}
main()
{
//char s[]="abcdab";
char s[]="3212134532156";
int i, maxlen, count;
unsigned long *maxlist = _maxlist(s, &count, &maxlen);
printf("字符串:\n%s\n不重复最长子串:\n", s);
for (i=0; i<count; i++)
printf("%.*s\n", maxlen, (unsigned long *)maxlist[i]);
free(maxlist);
}
[此贴子已经被作者于2016-12-12 20:40编辑过]