2014-01-21 6 views
2

У меня проблема со сравнением большого количества строковых данных (csv-файлов). Эти файлы имеют уникальныйID, но не отсортированы, и они довольно большие..Net C# String.GetHashCode() альтернативный

Поэтому я попытался создать два словаря, где ключ уникален от файла, а Value - int, который возвращает GetHashCode() строки, которая меня интересует для изменений.

Но, короткий пример:

if ("30000100153:135933:Wuchterlova:335:2:Praha:16000".GetHashCode() == 
    "30000263338:158364:Radošovická:1323:10:Praha:10000".GetHashCode()) 
{ 
    Console.WriteLine("Hmm that's strange"); 
} 

Так есть ли другой способ, как сделать это.

мне нужно как мало footprit, насколько это возможно (за счет выделения памяти двух dictionarie двух файлов CSV, который содержит около 3M строк) Спасибо вам

+0

Я думаю, вы найдете эту нить интересное: http://stackoverflow.com/questions/735317/hashtable-dictionary-collisions –

+3

Хеш коды не являются уникальными. Их просто не может быть, потому что возможны более строгие значения, даже в строках «Длина» 3 ((2^16)^3 = 2^48), чем возможные хэши (2^32). –

+0

Реализации 'GetHashCode' оптимизированы для скорости, а не для уникальности. Если вы хотите минимизировать риск столкновений, вместо этого используйте криптографическую функцию (например, SHA). – Douglas

ответ

17

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

Во-вторых, хэш-коды не являются уникальными. Есть только четыре миллиарда возможных хэш-кодов (потому что хеш-код представляет собой 32-битное целое число), но, очевидно, существует более четырех миллиардов строк, поэтому должно быть много строк, имеющих один и тот же хеш-код. Коллекция из нескольких тысяч строк имеет чрезвычайно высокую вероятность содержать две строки с одним и тем же хэш-кодом. График вероятности здесь:

http://blogs.msdn.com/b/ericlippert/archive/2010/03/22/socks-birthdays-and-hash-collisions.aspx

Таким образом, вы можете удивиться, как словарь работает на всех, то, если он использует GetHashCode, но могут быть столкновения. Ответ: когда вы помещаете две вещи X и Y в словарь, имеющие один и тот же хеш-код, они входят в одно и то же «ведро». Когда вы ищете X, словарь переходит в правое ведро с использованием хеш-кода, а затем выполняет дорогостоящую проверку равенства для каждого элемента в ведре до тех пор, пока не найдет правильный. Поскольку каждый ковш невелик, эта проверка выполняется достаточно быстро.

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

Я написал много статей по струнной хеширования, которые могли бы вас заинтересовать:

http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

http://blogs.msdn.com/b/ericlippert/archive/2011/07/12/what-curious-property-does-this-string-have.aspx

http://blogs.msdn.com/b/ericlippert/archive/2005/10/24/do-not-use-string-hashes-for-security-purposes.aspx

http://blogs.msdn.com/b/ericlippert/archive/tags/hashing/

+0

может использовать что-то вроде ленивого словаря загрузки, который будет загружать содержимое файлов по мере необходимости? –

+0

Ну, даже если он хранит свои строки в словаре, и даже если у него действительно возникнут хеш-коллизии, он все равно сможет уйти от него. Класс Dictionary должен обрабатывать конфликты, но, возможно, удар по производительности будет слишком большим для его приложения. –

+0

Проблема в том, что мне нужно сравнить старый/новый файл, чтобы найти добавленные/удаленные или измененные строки, которые в первом столбце имеют уникальный идентификатор. Она должна быть эффективной и достаточно быстрой. – avojacek

0

Вы фактически не хотите использовать GetHashCode , Вы должны просто сравнить строки напрямую. Однако сравнение каждой из 3-мерных строк с каждой из трех строк 3М будет затруднительным в любое разумное время без сортировки списков в первую очередь.

Мой подход был бы отсортировать каждый список первых (как это сделать, зависит от целого ряда вещей), прочитайте сначала сортируются от каждого - позволяет вызов, то А и В, а также:

  1. , если A = В то делать все, и прочитать следующий A и следующий B и повторите
  2. если а < B делать все, что и читать следующий A и повторите
  3. если A> B делать все, и прочитать следующий B и повторить

. . где D o независимо от того, что означает то, что требуется в этой ситуации, и повторите это, вернитесь к шагу 1.

(Этот процесс - это то, как компьютеры с мейнфреймом используются для объединения стопок карт и имеют определенное имя, но я не могу убей помню)

Приветствия -