c строка сравнения против хеш-сравнения - PullRequest
3 голосов
/ 08 августа 2010

Мне нужно сравнить строку с несколькими другими константными строками в c.Мне любопытно, что быстрее: для хеширования строки я собираюсь сравнить и сравнить ее со всеми другими константами хеш-строк или просто сравнить строки как строки.заранее спасибо

спасибо за ответы, которые я собираюсь сделать много сравнений.Может ли кто-нибудь дать мне хороший, быстрый и ресурсоемкий алгоритм для использования?Единственный хэш, который я знаю, это MD5, и у меня есть ощущение, что это слишком много.

Я также хочу добавить, что максимальная длина строки составляет, возможно, 20 или 30 символов, а большинство - около 7.

Ответы [ 11 ]

9 голосов
/ 08 августа 2010

Будет ли сравнение проводиться один или несколько раз? Если сравнение будет выполнено только один раз, то вам, вероятно, лучше сделать прямое сравнение. Если вам нужно сравнить очень много строк с этим набором константных строк, то вы, вероятно, сможете сэкономить время в долгосрочной перспективе, выполнив это с хешами.

Это достаточно простая проблема, которую вы можете легко написать в обоих направлениях и посмотреть, какой из них лучше подходит для репрезентативного набора входных данных.

4 голосов
/ 09 августа 2010

Сложно продвинуться вперед, функции хеширования строк O (n). Сравнение строк также равно O (n), с меньшим Oh. Вы были бы впереди только в том случае, если вы можете хранить хеш-значения, которые вы вычисляете, и использовать их повторно. Для обоих.

Простые примеры хэш-функций C здесь .

4 голосов
/ 08 августа 2010

Если вы пытаетесь сопоставить строку темы с набором других строк, вы можете использовать Алгоритм сопоставления строк Aho-Corasick . Он использует три для сопоставления объекта со всеми целевыми строками за один проход (это также довольно просто реализовать).

3 голосов
/ 09 августа 2010

Я думаю, что если у вас есть статический список строк, я бы сохранил их в отсортированном массиве, а затем использовал бы 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;
}
3 голосов
/ 08 августа 2010

Равенство хеш-значения не гарантирует равенство - однако несоответствие гарантирует неравенство. Если вам нужно сравнить множество строк с вашей коллекцией, то хеш был бы хорош - если это одноразовое сравнение (вряд ли, я думаю), тогда strcmp подойдет хорошо.

1 голос
/ 09 августа 2010

Если ваши константные строки известны во время компиляции, взгляните на идею «идеального хеша».

Википедия: Идеальная хеш-функция для множества S - это хеш-функция, которая отображает различные элементыв S для различных целых чисел, без коллизий.

Эта вещь "без коллизий" спасает вашу работу.Возможности для дальнейшего чтения и реализации:

1 голос
/ 08 августа 2010

Это зависит. Какой алгоритм хеширования? Как долго эти строки? Какая платформа?

Также обратите внимание, что соответствующий хеш не гарантирует совпадение строк.

0 голосов
/ 30 мая 2019

Чтобы ответить на ваш вопрос напрямую, если вы просто сравниваете, если две строки (вы также можете подумать о двух файлах, двух видео и т. Д.), Выполняете сравнение между символами и хэшированием, оба являются O (N), то очевидногопреимущество делает это хэш способом.

Однако, если строка может измениться, то хеширование будет более эффективным во 2-м цикле, например, переходящий хэш https://en.wikipedia.org/wiki/Rolling_hash

Более того, хеширование строки / файла похоже на отпечаток, вы можете напрямую сравнить хеш-значение в следующий раз, когда вы хотите сравнить, если другая строка такая же, как эта или нет

0 голосов
/ 09 августа 2010

спасибо за ответы, которые я собираюсь сделать много сравнений.Может ли кто-нибудь дать мне хороший, быстрый и ресурсоемкий алгоритм для использования?Единственный хеш, который я знаю, - это MD5, и у меня есть ощущение, что это слишком.

Хэш Murmur простой, быстрый и хорошо работает в статистических тестах.

0 голосов
/ 09 августа 2010

Другой подход, который может сработать, состоит в том, чтобы отсортировать вашу постоянную строку и выполнить дихотомический поиск вашей строки, таким образом, у вас есть только самое большее log2(n) сравнение (это, например, только 10 сравнений для 1024 строк или даже только 20за 1000000 строк).Я не знаю, применимо ли это к вашей проблеме, но у меня были действительно хорошие результаты при таком подходе.Хэширование действительно трудно понять правильно, угловые случаи могут быть очень неприятными, а вычисление ключа может быть довольно дорогостоящим.

...