Массивы / Списки и вычислительные хеш-значения (VB, C #) - PullRequest
0 голосов
/ 13 июня 2010

Я чувствую себя плохо, задавая этот вопрос, но в настоящее время я не могу запрограммировать и проверить это, поскольку пишу это на своем мобильном телефоне, а не на своем компьютере разработчика: P (Легко повторять, если кто-то отвечает! XD)

В любом случае, у меня был опыт использования хеш-значений из объектов String. Например, если у меня StringA и StringB оба равны "foo", они оба вычислят одно и то же значение хеш-функции, потому что для них установлены равные значения.

Теперь, что, если у меня есть список с T, являющимся собственным типом данных. Если бы я попытался вычислить хеш-значения ListA и ListB, предполагая, что они оба были бы одинакового размера и содержали бы одну и ту же информацию, разве они не имели бы одинаковые хеш-значения?

Предполагается, что в качестве образца набора данных «байта» длиной 5 {5,2,0,1,3}

Ответы [ 3 ]

2 голосов
/ 13 июня 2010

Это зависит от того, как вы вычисляете значение хеш-функции и как вы определяете равенство.Например, два разных экземпляра массива, которые содержат одинаковые значения, могут не считаться равными в зависимости от вашего приложения.В этом случае вы можете включить адрес или другое уникальное значение для каждого массива как часть хеш-функции.

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

1 голос
/ 13 июня 2010

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

public static int GetOrderedHashCode<T>(this IEnumerable<T> source)
{
    unchecked
    {
        int hash = 269;
        foreach (T item in source)
        {
            hash = (hash * 17) + item.GetHashCode;
        }
        return hash;
    }
}

Если порядок предметов не важен, вы можете сделать что-то вроде этого:

public static int GetUnorderedHashCode<T>(this IEnumerable<T> source)
{
    unchecked
    {
        int sum = 907;
        int count = 953;
        foreach (T item in source)
        {
            sum = sum + item.GetHashCode();
            count++
        }
        return 991 * sum * count;
    }
}

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

0 голосов
/ 13 июня 2010

Если вы говорите о встроенных типах списков, то нет, они не будут равны.Зачем?Поскольку List<T> является ссылочным типом, равенство сделает сравнение, чтобы увидеть, совпадают ли ссылки.Если вы создаете пользовательский тип списка, вы можете переопределить методы Equals и GetHashCode для поддержки этого поведения, но это не произойдет со встроенными типами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...