循环数组,更好,更快等等?

时间:2012-12-11 16:11:10

标签: c arrays algorithm search coding-style

我想实现一个Hash或类似PHP的数组。什么更好,选项a)或选项b)通过其键找到元素?

(所有变量都已设置并初始化,等等!)

A)

for( i = 0; i < ary->element_cnt && found == NULL; i++ ) {
    current_element = &(ary->elements[i]);
    if( 0 == memcmp(current_element->key, search_key, keysize) ) {
        found = current_element;
    }
}

b)

for( i = 0, current_element = &(ary->elements[i]) ; 
        i < ary->element_cnt &&  
        0 != memcmp(current_element->key, searchkey, keysize); 
        i++, current_element = &(ary->elements[i]) );
/*found = current_element;*/

第一个更好,因为它更易读/可维护吗?第二个会更快吗?

在一个大循环中做所有事情是“糟糕的风格”吗?

我知道,那里有更好的搜索算法,但这不是我的问题!

2 个答案:

答案 0 :(得分:5)

这两种算法都是O(N)算法 - 它们都只是循环遍历一个数组并为每个元素调用memcmp - 所以它们的表现应该相似。主观上,我认为第一个更好,因为它更容易阅读。

但是,按密钥实现查找的最佳方法不是像这样的线性搜索,而是使用专门的数据结构,如哈希表或平衡二叉树。像PHP这样的脚本语言通常使用哈希表来实现这样的查找。

答案 1 :(得分:3)

所有风格问题当然都是非常主观的。这种类型的东西有时会受到当地代码风格指南的“监管”。

我个人认为对memcmp()的调用有点过于“沉重”,我会把它写成:

for( i = 0; i < ary->element_cnt; ++i ) {
    current_element = &ary->elements[i];
    if( memcmp(current_element->key, search_key, keysize) == 0 )
        break;
}

这会删除循环标题中的found检查,因为这有效地检查了两次我不喜欢的内容。

如果我真的想要使用found,我会把它写成:

for( i = 0; i < ary->element_cnt && !found; ++i ) {
    current_element = &ary->elements[i];
    found = memcmp(current_element->key, search_key, keysize) == 0;
}

这会删除无意义的if并直接指定布尔值,我觉得这很好。