在指定字符串中查找子串,推荐试用Sunday算法,具体SunDay算法的介绍,推荐阅读下面网址:https://blog.csdn.net/q547550831/article/details/51860017。
作者根据Sunday算法,整理源码如下,其中,先实现SundayMemMem函数,这个函数实现的功能是:在指定长度的内存空间中,查找指定长度的字节序列,SundayStrStr函数进一步简单封装SundayMemMem,实现子串查询。源码已经由作者进行了充分的测试,可放心使用。谢谢!
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char* SundayMemMem(char* sText, int nTextLength, char* sKeyWord, int nKeyLength)
{
if(nKeyLength == 0)
{
return NULL;
}
if(nTextLength == 0)
{
return NULL;
}
if(nKeyLength > nTextLength)
{
return NULL;
}
int nPosArray[256];
memset(nPosArray, 0, 256*sizeof(int));
int i;
i = 0;
char* pShift;
pShift = sKeyWord + nKeyLength - 1;
char* pTail;
pTail = sKeyWord + nKeyLength;
while(pShift >= sKeyWord)
{
unsigned char ch;
ch = *pShift;
if(nPosArray[ch] == 0/*nKeyLength+1*/)
{
nPosArray[ch] = pTail - pShift;
i++;
if(i == 256)
{
break;
}
}
pShift--;
}
//
pShift = sText;
char* pOffset;
pOffset = sKeyWord;
char* pBase;
pBase = pShift;
int nMatched;
nMatched = 0;
char* pKeyTail = sKeyWord + nKeyLength;
char* pTextTail = sText + nTextLength;
while((pOffset < pKeyTail) && (pShift < pTextTail))
{
if (*pShift != *pOffset)
{
pShift = pBase + nKeyLength;
unsigned char ch;
ch = *pShift;
int nPos;
nPos = nPosArray[ch];
if(nPos == 0)
{
pBase += nKeyLength+1;
}
else
{
pBase += nPos;
}
pShift = pBase;
pOffset = sKeyWord;
nMatched = 0;
continue;
}
pShift++;
pOffset++;
nMatched++;
}
if(nMatched == nKeyLength)
{
return pBase;
}
else
{
return NULL;
}
}
char* SundayStrStr(char* sText, char* sKeyWord)
{
return SundayMemMem(sText, strlen(sText), sKeyWord, strlen(sKeyWord));
}
// 测试子串查询
int main(int argc, char* argv[])
{
char* sText = "1234567890abcedf";
char* pFind;
pFind = SundayStrStr(sText, "0abc");
if(pFind != NULL)
{
printf("pFind = %s\r\n", pFind );
}
else
{
printf("No find KeyWord\r\n" );
}
return 0;
}