所以我创建了自己的函数来比较两个C字符串:
bool list::compareString(const char array1[], const char array2[])
{
unsigned char count;
for (count = 0; array1[count] != '\0' && array2[count] != '\0' && (array1[count] == array2[count] || array1[count + 32] == array2[count] || array1[count] == array2[count+32]); count++);
if (array1[count] == '\0' && array2[count] == '\0')
return true;
else
return false;
}
我的for循环的参数非常长,因为它将计数带到至少一个字符串的末尾,并比较每个数组中的每个char
,以便它们的情况赢得'重要的是(将大写char
添加32将char
转换为小写的对应方式。)
现在,我猜测这是比较两个C字符串的最有效方法,但由于它的长度,for循环难以阅读。我被告知的是尽可能使用for循环而不是while循环,因为for循环在其起始参数中具有起始,结束和递增条件,但为此,这似乎可能不适用
我要问的是,我应该如何格式化这个循环,是否有更有效的方法呢?
答案 0 :(得分:5)
您可以直接在指针上操作,而不是使用count
索引到数组,而不是直接对指针进行操作:
bool list::compareString(const char* array1, const char* array2)
{
while (*array1 != '\0' || *array2 != '\0')
if (*array1++ != *array2++) return false; // not the same character
return true;
}
对于不区分大小写的比较,请将if条件替换为:
if (tolower(*array1++) != tolower(*array2++)) return false;
这可以安全地将字符转换为小写。
while循环检查字符串是否终止。它继续,而其中一个字符串尚未终止。如果只有1个字符串终止,则下一行 - if语句将意识到字符不匹配(因为只有1个字符是'\0'
,并返回false。
如果字符串在任何时候都不同,则if语句返回false。
if语句也会对指针进行后递增,以便它在while循环的下一次迭代中测试下一个字符。
如果两个字符串相等,并且在某个时刻同时终止,则while条件将变为false。在这种情况下,return true
语句将执行。
如果你想自己编写tolower
函数,你需要检查字符是大写字母,而不是不同类型的字符(例如,一些符号)。
这将是:
inline char tolower(char ch)
{
return (ch >= 'A' && ch <= 'Z' ? (ch + 'a' - 'A') : ch);
}
答案 1 :(得分:3)
我猜你在这里尝试进行不区分大小写的比较。如果您只需要最快的版本,请使用库函数:strcasecmp
或stricmp
或strcmpi
(名称取决于您的平台)。
如果您需要了解如何操作(我的意思是,您的问题是出于学习目的吗?),请从可读版本开始,如下所示:
for (index = 0; ; ++index)
{
if (array1[index] == '\0' && array2[index] == '\0')
return true; // end of string reached
if (tolower(array1[index]) != tolower(array2[index]))
return false; // different characters discovered
}
然后衡量其表现。如果它足够好,那就完成了。如果没有,请调查原因(通过查看编译器生成的机器代码)。优化的第一步可能用手工制作的代码替换tolower
库函数(忽略非英文字符 - 这是你想要做的吗?):< / p>
int tolower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
}
请注意,我仍然保持代码可读。可读代码可以很快,因为编译器将对其进行优化。
答案 2 :(得分:0)
array1 [count + 32] == array2 [count] 如果数组的长度小于32,则可能导致OutOfRangeException。 您可以使用strcmp比较两个字符串
答案 3 :(得分:0)
您的代码存在一些问题。
我在这里做的是将你的一些逻辑移到for循环的主体中。将所有内容塞入for循环表达式会大大降低可读性,而不会给您带来任何我能想到的性能提升。代码最终变得混乱。保持循环的条件以测试增量并将实际任务放在正文中。
我还指出你根本没有为角色添加32。您将其添加到数组的索引中会使您面临超出范围的风险。您需要在索引处测试值,而不是索引本身。
使用unsigned char为数组建立索引不会给您带来任何好处,只能减少您可以比较的字符串的最大长度。使用int。
您可以重新构建代码,使其如下所示:
bool list::compareString(const char array1[], const char array2[])
{
// Iterate over the strings until we find the string termination character
for (int count = 0; array1[count] != '\0' && array2[count] != '\0'; count++) {
// Note 0x20 is hexadecimal 32. We're comparing two letters for
// equality in a case insensitive way.
if ( (array1[count] | 0x20) != (array2[count] | 0x20) ) {
// Return false if the letters aren't equal
return false;
}
}
// We made it to the end of the loop. Strings are equal.
return true;
}
至于效率,在我看来,你正试图减少:
这些都不值得你花时间。效率是指执行任务需要多少步骤(不是代码行,请注意你)以及这些步骤随着输入变大而如何缩放。例如,比较两部小说的内容是否比两个单字串要慢多少?
我希望有帮助:)