一天一个CRT函数 strpbrk

一晃就是2月底了,在上个星期里完成了辞职手续。然而气愤的是,距离职仅有两天的时间,项目组长居然给我布置任务!靠,我直接拒绝了!更令人感到惊讶的是,他告诉我这个任务是他们不愿意做,又做不了的一个棘手问题,让我来帮他们搞定!!我骂人了,懂不懂管理啊!

废话不说了,看看strpbrk。

1.介绍

char*strpbrk( const char *string, const char *strCharSet );

用途:在源字符串(string)中找出最先含有搜索字符串(strCharSet )中的任一字符的位置并返回,若找不到则返回空指针

2.实现

/***
char *strpbrk(string, control) - scans string for a character from control

Purpose:
Finds the first occurence in string of any character from
the control string.

Entry:
char *string - string to search in
char *control - string containing characters to search for

Exit:
returns a pointer to the first character from control found
in string.
returns NULL if string and control have no characters in common.

***/
inline tChar *tStrPbrk(tChar *pStr, tChar *pStrSet)
{
// map有32个字节,就是256个bit的大小,可把map堪称一个2维数组[32][8]
unsigned char map[32] = {0};

// 每个ASCII码(设为c)有8bit,把它分为2部分,低3位构成下标j(通过c & 7得到),高5位构成下标i(通过c >> 3得到)
// 这样在map[i][j]中置1代表有字符存在
while(*pStrSet)
{
map[*pStrSet >> 3] |= (1 << (*pStrSet & 7));
pStrSet++;
}


while(*pStr)
{
// 如果有相同的字符则返回
if( map[*pStr >> 3] & (1 << (*pStr & 7)) )
return pStr++;

pStr++;
}

// 没有相同的字符返回NULL
return NULL;
}

tStrPbrk与 tStrcspn的算法一样,只是前者返回相同字符的指针位置,后者返回相同字符的个数。
 
2.测试
tChar string[] = _T("The 3 men and 2 boys ate 5 pigs/n");
tChar strFind[] = _T("0123456789");
tChar *result = NULL;

// Return pointer to first digit in "string".
result = CY_CRT::tStrPbrk( string, strFind );
wcout << result++ << endl;

result = CY_CRT::tStrPbrk( result, strFind );
wcout << result++ << endl;
result = CY_CRT::tStrPbrk( result, strFind );
wcout << result << endl;

 
3.分析

例如:对于字符’1’,其ASCII码味0x31,右移3位得到6,和7与运算得到1,也就是在map[6]中的第一位.

一个unsigend char有8位,拆违高5位与低3位。前5位的范围有0~32,所以申请32大小的数组map。直接将前5位映射成成数组下标,后3位范围0~7,正好是每一项char(8bit)。这个算法把时间与空间结合起来,效率非常高。

 

4.后记

在STL提供的算法里,find_first_of就是查找两个迭代器区间首次相同值位置的函数。在本系列完成后,我会出一个STL算法与CRT提供的功能函数进行横向比较。

你可能感兴趣的:(算法,String,null,search,character,任务)