//规则很简单,获取一个字符串的最长子串,要求这个子串中没有重复字符。字符穿中的字符均为ASCII字符
//下面的代码获取了所有最长无重复子串,即如果有多个满足条件的子串长度都相同,则全部输出
//如果只需要输出第一条最长子串,注释掉nTempLen == selData.m_Len判定分支的代码即可
//分析过程随后补上
#include "stdafx.h"
#include <string>
#include <vector>
using namespace std;
#ifndef byte
#define byte unsigned char
#endif
class SubStrData
{
public:
SubStrData(int beginPos, int len);
~SubStrData() {}
public:
int m_BeginPos;
int m_Len;
};
SubStrData::SubStrData(int beginPos = 0, int len = 0)
{
m_BeginPos = beginPos;
m_Len = len;
}
void GetMaxSubString(const char * strOrig, vector<SubStrData> & datas);
int _tmain(int argc, _TCHAR* argv[])
{
char buffIn[1024];
char buffOut[1024];
char *pch;
while ((pch = gets_s(buffIn, 1024)) != NULL)
{
vector<SubStrData> datas;
GetMaxSubString(buffIn, datas);
printf("Sub String Count = %d:\n", datas.size());
for (int i=0; i<datas.size(); i++)
{
strncpy_s(buffOut, buffIn + datas[i].m_BeginPos, datas[i].m_Len);
printf("Max SubString pos=%d, len=%d\n", datas[i].m_BeginPos, datas[i].m_Len);
printf("%s\n", buffOut);
}
}
return 0;
}
void GetMaxSubString(const char * strOrig, vector<SubStrData> & datas)
{
int len = strlen(strOrig);
int map[256];
for (int i=0; i<256; i++)
{
map[i] = -1;
}
SubStrData selData;
int nMaxLen = 0;
int nCheckingBegin = 0;
for (int i=0; i<len; i++)
{
if (map[(byte)strOrig[i]] == -1 || map[(byte)strOrig[i]] < nCheckingBegin)
{
map[(byte)strOrig[i]] = i;
}
else
{
int nTempLen = i - nCheckingBegin;
if (nTempLen > selData.m_Len)
{
selData.m_Len = nTempLen;
selData.m_BeginPos = nCheckingBegin;
datas.clear();
SubStrData dataItem = selData;
datas.push_back(dataItem);
}
else if (nTempLen == selData.m_Len)
{
SubStrData dataItem(nCheckingBegin, nTempLen);
datas.push_back(dataItem);
}
nCheckingBegin = map[(byte)strOrig[i]] + 1;
map[(byte)strOrig[i]] = i;
}
}
int nTempLen = len - nCheckingBegin;
if (nTempLen > selData.m_Len)
{
selData.m_Len = nTempLen;
selData.m_BeginPos = nCheckingBegin;
datas.clear();
SubStrData dataItem = selData;
datas.push_back(dataItem);
}
else if (nTempLen == selData.m_Len)
{
SubStrData dataItem(nCheckingBegin, nTempLen);
datas.push_back(dataItem);
}
}