【题目】求字符串的的最长不重复子串,即子串中没有重复字符。例如“abcad”的最长。。。为“bcad”;“abca”的最长。。。为“abc”。。。
void GetLongestNoRepeatedSubstring(char *str)
{
if (str==NULL || *str=='\0')
{
cout<<"Invalid Input"<<endl;
return;
}
int hashTable[256];
memset(hashTable,-1,256*sizeof(int));
int maxLen=0;
int len=strlen(str);
int i;
int curStart=0;//求本次子串长度的起始位置
int Index=curStart;//Index用于记录最长不重复子串的起始位置
for (i=0;i<len;i++)
{
if (hashTable[str[i]]==-1)//等于-1说明是第一次出现,不是重复字符
{
hashTable[str[i]]=i;//【注意】hashTable存储的是每个字符在原字符串中的“位置”
if (i-curStart+1>maxLen)
{ //此处maxlen的比较及计算与else中的第二个if不同,因为hashTable[str[i]]==-1
//说明出现的是非重复字符,应该算在此时的字符串中,即+1,比如计算"abcadef"中第二个a之后的字符时
maxLen=i-curStart+1;
Index=curStart;
}
}
else
{
if (hashTable[str[i]]<curStart)
{ //此时,尽管出现重复字符,但是重复字符出现在curStart之前,即不会影响本次不重复子串的计算
if (i-curStart+1>maxLen)
{
maxLen=i-curStart+1;
Index=curStart;
}
continue;
}
if (i-curStart>maxLen)//说明出现重复字符,并且重复字符出现在本次子串计算中,不应该把重复字符算账子串长度中,所以不+1
{
maxLen=i-curStart;
Index=curStart;
}
curStart=hashTable[str[i]]+1;//更新下一次curStart的位置,比如计算"abcadef"时,初始curStart=0,
hashTable[str[i]]=i;//重复字符的位置更新
}
}
cout<<"最长不重复子串长度为:"<<maxLen<<endl<<"子串为:";
for(i=Index;i<Index+maxLen;i++)
cout<<str[i];
cout<<endl;
}
void main()
{
char *str="";
cout<<"原字符串为:"<<str<<endl;
GetLongestNoRepeatedSubstring(str);
}
测试1:
测试2:
测试3:
测试4:
测试5:输入空串时
【注】1、上面的代码其实有好多重复、冗余的地方,还没来得及修改,应该还能精简一下代码。
2、其实上面函数应该返回最长不重复子串的长度和保存最长不重复子串,我直接打印输出了。