看不明白strspn和strcspn的实现

chenyu2202863 2009-12-05 09:11:45
这个是strspn的实现

int strspn (unsigned char *string, unsigned char *control)

{
unsigned char map[32];
int count;

for (count = 0 count < 32 count++)
map[count] = 0;
while (*control)
{
map[*control >> 3] |= (1 << (*control & 7));
control++;
}

if (*string)
{
while (map[*string >> 3] & (1 << (*string & 7)))
{
count++;
string++;
}

return(count);
}

return(0);
}


这是查表的方式来寻找字符串位置,问题是
不明白map[*control >> 3] |= (1 << (*control & 7));原理。

希望大家能帮我解读此代码~最后40分了~
...全文
347 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenyu2202863 2009-12-07
  • 打赏
  • 举报
回复
当然测过,只是我写上来的时候少了一些';'号。
bfhtian 2009-12-07
  • 打赏
  • 举报
回复
这段代码并不完整,不知道楼主自己测过没
chenyu2202863 2009-12-07
  • 打赏
  • 举报
回复
已经明白,再让坛里的朋友理解下。晚上揭帖
chenyu2202863 2009-12-07
  • 打赏
  • 举报
回复
我就是在看MS的CRT系列函数时发现的,这个算法很强悍,很不容易看懂。
所以来请教大家,我再仔细琢磨琢磨
guolihui112 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 logiciel 的回复:]
引用 8 楼 guolihui112 的回复:
对于参数 string, 和 control

1. 将 control 存放到数组中相应位置( 数组地点: 下表:前5位计算得到. 位位置:后3位计算得到. )
2. 遍历 string, 对每个string的字符查看 数组中相应的位置是否有存在.

但是这个样子只是比较 string 的某个字符在 control 中是否存在,看下边:

strspn( "ggoo", "oogg" ) 得到的结果会是 4




调用C中的strspn,strspn( "ggoo", "oogg" ) 得到的结果也是4。

[/Quote]

哦, 还真没用过
logiciel 2009-12-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 guolihui112 的回复:]
对于参数 string, 和 control

1. 将 control 存放到数组中相应位置( 数组地点: 下表:前5位计算得到. 位位置:后3位计算得到. )
2. 遍历 string, 对每个string的字符查看 数组中相应的位置是否有存在.

但是这个样子只是比较 string 的某个字符在 control 中是否存在,看下边:

strspn( "ggoo", "oogg" ) 得到的结果会是 4
[/Quote]

调用C中的strspn,strspn( "ggoo", "oogg" ) 得到的结果也是4。
logiciel 2009-12-06
  • 打赏
  • 举报
回复
例如,对于字符‘1’,其ASCII码是0x31,>>3得6,&7得1,也就是它在map[6]的第1位,通过1<<1得1,然后与map[6]相与.

上帖中说的下标j就是在map[i]中的第j位.
guolihui112 2009-12-06
  • 打赏
  • 举报
回复
对于参数 string, 和 control

1. 将 control 存放到数组中相应位置( 数组地点: 下表:前5位计算得到. 位位置:后3位计算得到. )
2. 遍历 string, 对每个string的字符查看 数组中相应的位置是否有存在.

但是这个样子只是比较 string 的某个字符在 control 中是否存在,看下边:

strspn( "ggoo", "oogg" ) 得到的结果会是 4
guolihui112 2009-12-06
  • 打赏
  • 举报
回复
主要还是比较功能上动了些心思.
一个 unsigned char 有 8 位, 这里是拆成5 位和 后3位两部分.
前5位表示的范围有 32 个.所以申请了 32 大小的数组 map, 直接将 前5位 映射成数组的下标,不错.
然后后3位表示 0~7 这8个数值.正好map的每一项是 char (8位)的,所以 后3位就存放到相应的位上.
logiciel 2009-12-05
  • 打赏
  • 举报
回复
上面代码中if (*string)后漏了count = 0;

map有32个字节。就是256个BIT,可把map看成是一个2维数组[32][8],

每个ASCII码(设为c)有8BIT,把它分为2部分,低3位构成下标j(通过c & 7得到),高5位构成下标i(通过c>>3得到),这样在map[[i][j]中置1代表该字符存在。

算法中先根据control构成map,然后把string中每个字符用同样方法计算出i和j,如果map[i][j]为1,则count加1 。

wwwr 2009-12-05
  • 打赏
  • 举报
回复
我晕!这几行代码谁知道啊!天书!
sduxiaoxiang 2009-12-05
  • 打赏
  • 举报
回复
map[*control >> 3] =map[*control >> 3]| (1 < < (*control & 7))
chenyu2202863 2009-12-05
  • 打赏
  • 举报
回复
顶起来
macrojj 2009-12-05
  • 打赏
  • 举报
回复
额 前排占座

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧