【问题标题】:c string compare vs hash comparec字符串比较与哈希比较
【发布时间】:2011-03-27 00:34:09
【问题描述】:

我需要将一个字符串与 c 中的多个其他常量字符串进行比较。我很好奇哪个更快,散列我要比较的字符串并将其与所有其他常量字符串散列进行比较,或者只是将字符串作为字符串进行比较。提前谢谢你

感谢您的回答,我将进行多次比较。谁能给我一个好的、快速的、低资源密集型的算法来使用?我知道的唯一哈希值是 MD5,我有一种过度杀戮的感觉。

我还想补充一点,这些字符串最多可能有 20 或 30 个字符,大多数在 7 左右。

【问题讨论】:

    标签: c string hash compare


    【解决方案1】:

    比较会进行一次还是多次?如果比较只进行一次,那么您最好进行直接比较。如果您需要将很多字符串与这组常量字符串进行比较,那么从长远来看,您可以通过使用哈希来节省时间。

    这是一个非常简单的问题,您可以轻松地以两种方式编写它,看看哪种方式更适合具有代表性的输入集。

    【讨论】:

      【解决方案2】:

      很难取得成功,字符串散列函数是 O(n)。字符串比较也是 O(n),而且 Oh 更小。如果您可以存储您计算的哈希值并重复使用它们,您只会领先。对于两者。

      简单的示例 C 哈希函数are here

      【讨论】:

      • 如果您将这个字符串与多个字符串进行比较 - 就像问题所问的那样?我不认为它仍然是 O(n),它会是 O(n^2) 对吗?
      【解决方案3】:

      如果您尝试将主题字符串与一组其他字符串进行匹配,您可以考虑使用Aho-Corasick String Matching Algorithm。它使用 trie 一次将主题与所有目标字符串进行匹配(实现起来也很简单)。

      【讨论】:

        【解决方案4】:

        哈希值的相等并不能保证相等 - 但是,不匹配将保证不相等。如果您需要将大量字符串与您的集合进行比较,那么哈希会很棒 - 如果它是一次性比较(我猜不太可能),那么 strcmp 会做得很好。

        【讨论】:

        【解决方案5】:

        我想如果你有一个静态的字符串列表,我会将它们存储在一个排序数组中,然后使用bsearch 来确定一个字符串是否在该列表中。如果它不存在,则返回 NULL,如果存在则返回指向该值的指针,并且可能比线性搜索或散列更快。

        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        
        /* cmp function for qsort and bsearch */
        static int pstrcmp(const void *a, const void *b)
        {
          return strcmp(*(char * const *)a, *(char * const *)b);
        }
        
        /* check an input against the list of known strings */
        static char *check_for_match(char *input)
        {
          static char *static_list[] = { "one", "two", "three", "four", "five" };
          static int nelems;
        
          /* this sorts the list, for demonstration purposes, but if the list
             is static then it could be sorted prior to compiling */
          if (! nelems)
          {
            nelems = sizeof(static_list) / sizeof(*static_list);
            qsort(static_list, nelems, sizeof(*static_list), pstrcmp);
          }
        
        
          return bsearch(&input, static_list, nelems, sizeof(*static_list), pstrcmp);
        }
        
        int main(int argc, char *argv[])
        {
          if (check_for_match("should_not_match"))
          {
            printf("Match found.\n");
          } else {
            printf("No match found.\n");
          }
        
          if (check_for_match("two"))
          {
            printf("Match found.\n");
          } else {
            printf("No match found.\n");
          }
          return EXIT_SUCCESS;
        }
        

        【讨论】:

          【解决方案6】:

          这取决于。什么是哈希算法?琴弦有多长?什么平台?

          另请注意,匹配的哈希值并不能保证匹配的字符串。

          【讨论】:

          • 散列没有误报,但确实有误报。
          【解决方案7】:

          如果您的常量字符串在编译时已知,请查看“完美哈希”的概念。

          维基百科:集合 S 的完美散列函数是将 S 中的不同元素映射到不同整数的散列函数,没有冲突。

          “无冲突”可以节省您的工作量。进一步阅读和实施的可能性是:

          【讨论】:

            【解决方案8】:

            这在很大程度上取决于字符串的长度和散列函数的复杂性。自己实施和基准测试将是最好的答案...

            【讨论】:

              【解决方案9】:

              另一种可行的方法是对常量字符串进行排序并对字符串进行二分搜索,这样您最多只有log2(n) 比较(例如,对于 1024 个字符串只有 10 次比较,甚至只有 20 1000000 个字符串)。 我不知道它是否适用于您的问题,但我用这种方法取得了非常好的结果。散列确实很难正确处理,极端情况会变得非常糟糕,并且密钥的计算通常会非常昂贵。

              【讨论】:

                【解决方案10】:

                谢谢你的答案我要去 要做很多比较。能够 谁给我一个好,快,低 使用资源密集型算法? 我知道的唯一哈希是 MD5 和我 有种杀过去的感觉。

                Murmur hash 简单、快速并且在统计测试中表现良好。

                【讨论】:

                  【解决方案11】:

                  直接回答你的问题,如果你只是比较两个字符串(你也可以考虑两个文件,两个视频等),逐个字符比较和散列都是 O(N),没有明显的这样做的好处是散列方式。

                  但是,如果字符串可以更改,那么在第二次运行时散列会更有效,例如,滚动散列 https://en.wikipedia.org/wiki/Rolling_hash

                  而且,字符串/文件的哈希就像指纹一样,下次你想比较另一个字符串是否与这个相同时,你可以直接比较哈希值

                  【讨论】:

                    猜你喜欢
                    • 2015-03-07
                    • 2021-03-26
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多