【发布时间】:2011-04-05 21:02:11
【问题描述】:
有人知道memcspn 函数的有效实现吗?它的行为应该类似于 strcspn,但在内存缓冲区中而不是在以空字符结尾的字符串中查找跨度。目标编译器是visualC++。
谢谢, 卢卡
【问题讨论】:
有人知道memcspn 函数的有效实现吗?它的行为应该类似于 strcspn,但在内存缓冲区中而不是在以空字符结尾的字符串中查找跨度。目标编译器是visualC++。
谢谢, 卢卡
【问题讨论】:
为这个函数编写一个低效的实现似乎相当困难,TBH - 实现看起来很简单,所以如果您在合理的时间范围内找不到实现,我建议您自己编写。
【讨论】:
wchar_t,低效的实现是唯一实用的实现,它是O(nm)。
O((m + n) log m) 的实现并不难(排序needle,然后在其中进行二进制搜索而不是线性搜索)。与您的方法类似但使用哈希表而不是简单数组的方法适用于 32 位 wchar_t 并且在平均情况下具有相似的运行时间。
O(m),因为您需要工作空间来复制它。可以想象,这可能会使该方法不可行。至少你需要一个大型集合的后备案例。
set 参数已经排序......如果你可以做到这一点。
一个近乎最佳的实现:
size_t memcspan(const unsigned char *buf, size_t len, const unsigned char *set, size_t n)
{
size_t i;
char set2[1<<CHAR_BIT] = {0};
while (n--) set2[set[n]] = 1;
for (i=0; i<len && !set2[buf[i]]; i++);
return i;
}
对于set2,使用位数组而不是字节数组可能会更好,具体取决于算术或更多缓存抖动在您的计算机上是否更昂贵。
【讨论】:
strcspn() 与strpbrk() 混淆了。后者从set 返回指向第一个实例的指针,前者返回第一个实例的偏移量。显然,除了buf 中没有set 的成员的极端情况之外,同样的底层逻辑也可以满足您的需求。