【问题标题】:Efficient memcspn高效内存
【发布时间】:2011-04-05 21:02:11
【问题描述】:

有人知道memcspn 函数的有效实现吗?它的行为应该类似于 strcspn,但在内存缓冲区中而不是在以空字符结尾的字符串中查找跨度。目标编译器是visualC++。

谢谢, 卢卡

【问题讨论】:

    标签: c assembly strchr


    【解决方案1】:

    为这个函数编写一个低效的实现似乎相当困难,TBH - 实现看起来很简单,所以如果您在合理的时间范围内找不到实现,我建议您自己编写。

    【讨论】:

    • 实际上很容易编写一个低效的实现——对于大型字符集,例如32位wchar_t,低效的实现是唯一实用的实现,它是O(nm)
    • @R.:嗯,O((m + n) log m) 的实现并不难(排序needle,然后在其中进行二进制搜索而不是线性搜索)。与您的方法类似但使用哈希表而不是简单数组的方法适用于 32 位 wchar_t 并且在平均情况下具有相似的运行时间。
    • 对“needle”(有点用词不当 - 实际上是字符集)进行排序是空间中的O(m),因为您需要工作空间来复制它。可以想象,这可能会使该方法不可行。至少你需要一个大型集合的后备案例。
    • 当然,更明智的设计是只要求 set 参数已经排序......如果你可以做到这一点。
    • @all:非常好的观点——我认为搜索字符只不过是几个字符——所以缺乏二分搜索确实使这种幼稚的方法效率低得多。跨度>
    【解决方案2】:

    一个近乎最佳的实现:

    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 的成员的极端情况之外,同样的底层逻辑也可以满足您的需求。
    猜你喜欢
    • 2019-07-09
    • 1970-01-01
    • 2018-04-20
    • 2017-01-26
    • 2017-01-27
    • 2017-10-06
    • 2011-02-26
    • 1970-01-01
    相关资源
    最近更新 更多