Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何有效地用相同长度的其他字符串替换一组子字符串?_C_String_Replace - Fatal编程技术网

C 如何有效地用相同长度的其他字符串替换一组子字符串?

C 如何有效地用相同长度的其他字符串替换一组子字符串?,c,string,replace,C,String,Replace,我有一组目标字符串及其替换: " </3" "\xf0\x9f\x92\x94" " <3 " "\xf0\x9f\x92\x97" " 8-D" "\xf0\x9f\x98\x81" " 8D " "\xf0\x9f\x98\x81" " x-D" "\xf0\x9f\x98\x81" " xD " "\xf0\x9f\x98\x81" " :')" "\xf0\x9f\x98\x82" ":'-)" "\xf0\x9f\x98\x82" ":-))" "\xf0

我有一组目标字符串及其替换:

" </3"  "\xf0\x9f\x92\x94"
" <3 "  "\xf0\x9f\x92\x97"
" 8-D"  "\xf0\x9f\x98\x81"
" 8D "  "\xf0\x9f\x98\x81"
" x-D"  "\xf0\x9f\x98\x81"
" xD "  "\xf0\x9f\x98\x81"
" :')"  "\xf0\x9f\x98\x82"
":'-)"  "\xf0\x9f\x98\x82"
":-))"  "\xf0\x9f\x98\x83"
" 8) "  "\xf0\x9f\x98\x84"
" :) "  "\xf0\x9f\x98\x84"
" :-)"  "\xf0\x9f\x98\x84"
" =) "  "\xf0\x9f\x98\x84"
" =] "  "\xf0\x9f\x98\x84"
" 0:)"  "\xf0\x9f\x98\x87"
"0:-)"  "\xf0\x9f\x98\x87"
...
第一种方法应该更快,如果我可以:

  • 以某种方式匹配所有表情符号字符串。。。就像DFA。A可能会派上用场
  • 映射匹配的字符串及其替换项,而无需编码C++的等价物
    std::map
如何有效地实现这两种方法中的任何一种?我还有其他选择吗


全面披露:


这是测试的一部分。

如果数据有可能更改,您可能需要使用某种映射(例如哈希表或trie)。在这里覆盖这些理论似乎是不必要的,特别是考虑到问题中没有提到这个选项。。。我只是想提一些值得思考的东西

否则,数据就不会改变,我强烈建议使用排序查找表,这是第一个选项的优化版本,因此您可以使用二进制搜索,而不是从数组的开始到结束进行搜索。例如:

struct replacement {
    char original[4];
    char replacement[4];
};

int compare_replacement(void const *x, void const *y) {
    struct replacement const *fu = x, *ba = y;
    return memcmp(x->original, y->original, 4);
}

int main(void) {
    struct replacement table[] = {
        { .original = " </3" , .replacement = "\xf0\x9f\x92\x94" },
        { .original = " <3 " , .replacement = "\xf0\x9f\x92\x97" },
        { .original = " 8-D" , .replacement = "\xf0\x9f\x98\x81" },
        { .original = " 8D " , .replacement = "\xf0\x9f\x98\x81" },
        { .original = " x-D" , .replacement = "\xf0\x9f\x98\x81" },
        { .original = " xD " , .replacement = "\xf0\x9f\x98\x81" },
        { .original = " :')" , .replacement = "\xf0\x9f\x98\x82" },
        { .original = ":'-)" , .replacement = "\xf0\x9f\x98\x82" },
        { .original = ":-))" , .replacement = "\xf0\x9f\x98\x83" },
        { .original = " 8) " , .replacement = "\xf0\x9f\x98\x84" },
        { .original = " :) " , .replacement = "\xf0\x9f\x98\x84" },
        { .original = " :-)" , .replacement = "\xf0\x9f\x98\x84" },
        { .original = " =) " , .replacement = "\xf0\x9f\x98\x84" },
        { .original = " =] " , .replacement = "\xf0\x9f\x98\x84" },
        { .original = " 0:)" , .replacement = "\xf0\x9f\x98\x87" },
        { .original = "0:-)" , .replacement = "\xf0\x9f\x98\x87" }
    };

    qsort(table, sizeof table / sizeof *table, sizeof *table, compare_replacement);
}
void replace_emotes(char *str, struct replacement *rep, size_t rep_size) {
    while (*str) {
        struct replacement query = { 0 };
        strncpy(query.original, rep, sizeof query.original);

        struct replacement *response = bsearch(&query, rep, rep_size, sizeof *rep, compare_replacement);
        if (response) {
            strncpy(str, response->replacement, sizeof response->replacement);
        }
    }
}


如果您打算支持插入,首先需要使用
realloc
。。。并在插入前确定插入位置以保持数组排序,或者在每次插入后使用数组。这两种方法中的任何一种都适用于对小集合的修改(插入和删除),但如果您打算支持较大的集合,则可能需要使用trie或哈希表之类的工具。

即使对于测试,这听起来也有点像过早优化。我只想用一种明显的方法:(1)检查字符是否是最后的字符之一,(2)如果是,扫描替换列表并应用一个替换字符(如果适用)。@roeland True。事实上,我正在考虑使用正则表达式,因为a)我以前不必在C中使用正则表达式,我可以在一个正则表达式中组合几个等效的表情符号。也就是说,我仍然想知道一个专家会如何处理这个问题。在C++ 11中有一个<代码> <代码>标题,但在C中没有。如果你真的在谈论C++,请确保你把问题标记为C++。正则表达式的方式可能更明显,也可能足够快。@roeland有一个POSIX是用来与C结合使用的,我在我的帖子中提到了POSIX库。然而,没有C++。
void replace_emotes(char *str, struct replacement *rep, size_t rep_size) {
    while (*str) {
        struct replacement query = { 0 };
        strncpy(query.original, rep, sizeof query.original);

        struct replacement *response = bsearch(&query, rep, rep_size, sizeof *rep, compare_replacement);
        if (response) {
            strncpy(str, response->replacement, sizeof response->replacement);
        }
    }
}