我刚开始接受C编程,并会对我的ReplaceString函数表示赞赏。 它似乎非常快(它没有为结果字符串分配除一个malloc之外的任何内存)但它看起来非常冗长,我知道它可以做得更好。
使用示例:
printf("New string: %s\n", ReplaceString("great", "ok", "have a g grea great day and have a great day great"));
printf("New string: %s\n", ReplaceString("great", "fantastic", "have a g grea great day and have a great day great"));
代码:
#ifndef uint
#define uint unsigned int
#endif
char *ReplaceString(char *needle, char *replace, char *haystack)
{
char *newString;
uint lNeedle = strlen(needle);
uint lReplace = strlen(replace);
uint lHaystack = strlen(haystack);
uint i;
uint j = 0;
uint k = 0;
uint lNew;
char active = 0;
uint start = 0;
uint end = 0;
/* Calculate new string size */
lNew = lHaystack;
for (i = 0; i < lHaystack; i++)
{
if ( (!active) && (haystack[i] == needle[0]))
{
/* Start of needle found */
active = 1;
start = i;
end = i;
}
else if ( (active) && (i-start == lNeedle) )
{
/* End of needle */
active = 0;
lNew += lReplace - lNeedle;
}
else if ( (active) && (i-start < lNeedle) && (haystack[i] == needle[i-start]) )
{
/* Next part of needle found */
end++;
}
else if (active)
{
/* Didn't match the entire needle... */
active = 0;
}
}
active= 0;
end = 0;
/* Prepare new string */
newString = malloc(sizeof(char) * lNew + 1);
newString[sizeof(char) * lNew] = 0;
/* Build new string */
for (i = 0; i < lHaystack; i++)
{
if ( (!active) && (haystack[i] == needle[0]))
{
/* Start of needle found */
active = 1;
start = i;
end = i;
}
else if ( (active) && (i-start == lNeedle) )
{
/* End of needle - apply replacement */
active = 0;
for (k = 0; k < lReplace; k++)
{
newString[j] = replace[k];
j++;
}
newString[j] = haystack[i];
j++;
}
else if ( (active) && (i-start < lNeedle) && (haystack[i] == needle[i-start])
)
{
/* Next part of needle found */
end++;
}
else if (active)
{
/* Didn't match the entire needle, so apply skipped chars */
active = 0;
for (k = start; k < end+2; k++)
{
newString[j] = haystack[k];
j++;
}
}
else if (!active)
{
/* No needle matched */
newString[j] = haystack[i];
j++;
}
}
/* If still matching a needle... */
if ( active && (i-start == lNeedle))
{
/* If full needle */
for (k = 0; k < lReplace; k++)
{
newString[j] = replace[k];
j++;
}
newString[j] = haystack[i];
j++;
}
else if (active)
{
for (k = start; k < end+2; k++)
{
newString[j] = haystack[k];
j++;
}
}
return newString;
}
有什么想法吗?非常感谢!
答案 0 :(得分:3)
不要叫strlen(haystack)。您已经在检查字符串中的每个字符,因此计算字符串长度对于循环是隐含的,如下所示:
for (i = 0; haystack[i] != '\0'; i++)
{
...
}
lHaystack = i;
答案 1 :(得分:2)
你有可能以自己的方式做这个练习。如果是这样,你会得到很多积分。
如果没有,您通常可以使用C运行时库(CRT)中的函数与编写自己的等效函数来节省时间。例如,您可以使用strstr来找到要替换的字符串。其他字符串操作函数也可能对您有用。
一个很好的练习是让你满意地完成这个例子,然后使用CRT重新编码,看看编码和执行的速度有多快。
答案 2 :(得分:1)
在第一次循环时,您应该将索引保留在需要替换的位置,并跳过函数的strcopy / replace部分。这将导致一个循环,您只能从haystack执行strncpy或替换为新的字符串。
答案 3 :(得分:0)
制作参数const
char *ReplaceString(const char *needle, const char *replace, const char *haystack)
哦......这个函数应该只用于每个单词一次吗?
ReplaceString("BAR", "bar", "BARBARA WENT TO THE BAR")的
答案 4 :(得分:0)
我的一个建议与提高性能无关,但提高了可读性。
“可爱”参数名称比描述性名称更难理解。您认为以下哪个参数能够更好地传达其目的?
char *ReplaceString(char *needle, char *replace, char *haystack)
char *ReplaceString(char *oldText, char *newText, char *inString)
有了一个,你必须有意识地将名字映射到一个目的。另一方面,目的是名称。在尝试理解一段代码时,在脑海中处理一堆名称映射会变得很困难,尤其是随着变量数量的增加。
当您是唯一一个使用您的代码的人时,这似乎并不那么重要,但是当您的代码被其他人使用或阅读时,这一点至关重要。有时候,“别人”就是你自己,一年后,看着你自己的代码,想知道你为什么要搜索干草堆并试图更换针头;)