程序的一部分需要在搜索有序列表时检查两个c字符串是否相同(例如@dimen/custom_switcher_circle_size
)。列表可能会变得非常大,因此速度的小幅提升值得降低可读性。假设您仅限于C ++(请不要建议切换到汇编)。如何改进?
{"AAA", "AAB", "ABA", "CLL", "CLZ"}
您可以假设typedef char StringC[5];
void compare (const StringC stringX, const StringC stringY)
{
// use a variable so compareResult won't have to be computed twice
int compareResult = strcmp(stringX, stringY);
if (compareResult < 0) // roughly 50% chance of being true, so check this first
{
// no match. repeat with a 'lower' value string
compare(stringX, getLowerString() );
}
else if (compareResult > 0) // roughly 49% chance of being true, so check this next
{
// no match. repeat with a 'higher' value string
compare(stringX, getHigherString() );
}
else // roughly 1% chance of being true, so check this last
{
// match
reportMatch(stringY);
}
}
和stringX
的长度始终相同,并且您不会收到任何无效的数据输入。
根据我的理解,编译器会生成代码,以便CPU检查第一个if语句并跳转,如果它是假的,那么最好是第一个语句最可能是真的,如跳转干扰管道。我还听说在进行比较时,[英特尔] CPU会进行减法并查看标志的状态而不保存减法的结果。有没有办法做stringY
一次,而不将结果保存到变量中,但仍然可以在前两个if语句中检查结果?
答案 0 :(得分:3)
std::binary_search
可能会有所帮助:
bool cstring_less(const char (&lhs)[4], const char (&rhs)[4])
{
return std::lexicographical_compare(std::begin(lhs), std::end(lhs),
std::begin(rhs), std::end(rhs));
}
int main(int, char**)
{
const char cstrings[][4] = {"AAA", "AAB", "ABA", "CLL", "CLZ"};
const char lookFor[][4] = {"BBB", "ABA", "CLS"};
for (const auto& s : lookFor)
{
if (std::binary_search(std::begin(cstrings), std::end(cstrings),
s, cstring_less))
{
std::cout << s << " Found.\n";
}
}
}
答案 1 :(得分:0)
我认为使用哈希表可以大大提高比较速度。此外,如果您的程序是多线程的,您可以在intel线程构建块库中找到一些有用的哈希表。例如,tbb :: concurrent_unordered_map与std :: unordered_map具有相同的api
我希望它可以帮到你。
答案 2 :(得分:0)
如果您尝试将所有字符串相互比较,则会遇到O(N*(N-1))
问题。最好的事情,正如您所说的那样,列表可能会变大,就是对它们进行排序(qsort
算法有O(N*log(N))
),然后将每个元素与列表中的下一个元素进行比较,添加了一个新的O(N)
,总计O(N*log(N))
总复杂度。当你有已经订购的列表时,你可以遍历它(制作事物O(N)
),将每个元素与下一个元素进行比较。一个在C和C ++中有效的例子如下:
for(i = 0; i < N-1; i++) /* one comparison less than the number of elements */
if (strcmp(array[i], array[i+1]) == 0)
break;
if (i < N-1) { /* this is a premature exit from the loop, so we found a match */
/* found a match, array[i] equals array[i+1] */
} else { /* we exhausted al comparisons and got out normally from the loop */
/* no match found */
}