以下是优化后的核心代码:

// 在字符串 haystack 中查找第一次出现 needle 的位置,返回指向该位置的指针,如果找不到则返回 null private char* strstrCase(char* haystack, const char* needle, bool isCaseSensitive) @nogc nothrow { if (!haystack || !needle || !*needle) { return haystack; }

size_t haystackLen = strlen(haystack);
size_t needleLen = strlen(needle);

if (needleLen > haystackLen)
{
    return null;
}

if (isCaseSensitive)
{
    return strstr(haystack, needle);
}
else
{
    char* p = haystack;
    while ((p = strcasestr(p, needle)) != null)
    {
        // 判断找到的位置是否在单词边界上
        if ((p == haystack || !isalpha(*(p - 1))) && !isalpha(*(p + needleLen)))
        {
            return p;
        }
        p += needleLen;
    }
    return null;
}

}

// 替换字符串中的子串 ref T replaceString(T)(auto ref T allStr,auto ref T searchStr,auto ref T replaceStr, bool isCaseSensitive=true) { static if(is(T==wstring)) { long index = 0; while ((index = isCaseSensitive ? allStr.indexOf(searchStr, index) : allStr.toLowerAll().indexOf(searchStr.toLowerAll(), index)) != -1) { allStr = allStr[0 .. index] ~ replaceStr ~ allStr[index + searchStr.length .. $]; index += replaceStr.length; } return allStr; } else static if(is(T==string)) { auto allStrPtr = toUTFz!(char*)(allStr); auto searchStrPtr = searchStr.ptr; auto replaceStrPtr = replaceStr.ptr;

    char* result = null;

    if (isCaseSensitive)
    {
        result = replaceCstr(allStrPtr, searchStrPtr, replaceStrPtr, true);
    }
    else
    {
        // 先复制一份原始字符串
        char* tempStr = cast(char*) malloc(strlen(allStrPtr) + 1);
        strcpy(tempStr, allStrPtr);

        // 用 strcasestr 查找子串并替换
        char* p = tempStr;
        while ((p = strstrCase(p, searchStrPtr, false)) != null)
        {
            char* q = result ? result + strlen(result) : allStrPtr;
            size_t length = p - tempStr;

            // 复制替换前的部分
            memmove(q, tempStr, length);
            q += length;

            // 复制替换后的部分
            memcpy(q, replaceStrPtr, strlen(replaceStrPtr));
            q += strlen(replaceStrPtr);

            // 更新指针和长度
            p += strlen(searchStrPtr);
            tempStr = p;

            // 重新分配内存
            size_t newLen = strlen(allStrPtr) + (q - (result ? result + strlen(result) : allStrPtr));
            result = cast(char*) realloc(result, newLen + 1);
        }

        // 复制剩余部分
        strcpy(result + strlen(result), tempStr);

        // 释放临时字符串
        free(tempStr);
    }

    // 将结果转换为字符串
    allStr = fromStringz(result).idup;

    // 释放内存
    if (allStrPtr != result)
    {
        free(result);
    }

    return allStr;
}

}

优化后的代码主要针对两个函数进行了改进:

  1. strstrCase 函数:

原来的实现方式是遍历整个字符串 haystack,逐个比较字符是否相等。这种实现方式效率比较低,尤其是在字符串 haystack 很长的情况下。优化后的实现方式是根据 isCaseSensitive 参数决定是否区分大小写,如果是区分大小写,则直接调用标准库函数 strstr;如果是不区分大小写,则调用 strcasestr 函数查找子串,并判断找到的位置是否在单词边界上。

  1. replaceString 函数:

原来的实现方式是先将字符串转换为 UTF-8 编码的 C 字符串,然后用 replaceCstr 函数替换子串,最后再将结果转换为字符串。这种实现方式虽然使用了 nogc,但是效率比较低。优化后的实现方式是根据 isCaseSensitive 参数决定调用哪个函数,如果是区分大小写,则调用原来的实现方式;如果是不区分大小写,则先将字符串复制一份,然后用 strcasestr 函数查找子串并替换,最后再将结果转换为字符串。这种实现方式虽然没有使用 nogc,但是效率比较高

我有以下D语言代码import stdstdio;import corestdcstdioprintf;import corestdcstring;import corestdcstdlib malloc free;import corestdcctypetolower;import stdtoUTFz;import stdstringfromStringztoStringz;import st

原文地址: https://www.cveoy.top/t/topic/fss9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录