Лучшая коллекция для использования с типом Double в качестве ключа - PullRequest
2 голосов
/ 10 февраля 2012

У меня есть этот объект:

Public Cactus{
    Public Double key;
    Public String value;
}

У меня есть ~ 100 Cactus, у каждого из которых есть уникальный ключ, и значение, которое имеет несколько дубликатов.Однако мне придется получить значение для ключа около 2000 раз.Мои значения Key варьируются от -10 до 280.

Я хочу, чтобы этот процесс был максимально быстрым.Что будет лучшим подходом для этого?Я думал об использовании HashTable, хотя я всегда использовал один с Integer, а не Double, и по какой-то причине я боюсь, что не стоит использовать Double как Key.

Учитывая мой сценарий, какую коллекцию лучше всего использовать?

Ответы [ 4 ]

10 голосов
/ 10 февраля 2012

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

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

Если вам не нужны точные совпадения, а нужно просто найти самое близкое значение, рассмотрите что-то вроде SortedList.

2 голосов
/ 19 сентября 2016

Я согласен с @Mark Byers и @tafa, что использование double в качестве ключа напрямую является плохой идеей. Если вы хотите убедиться, что у вас точно такой же номер, вы можете создать строковый ключ, основанный на байтах, которые составляют двойное число. Следующая структура отображает двойное число в том же пространстве памяти, что и 8 байт, так что никакого специального преобразования не требуется.

[StructLayout(LayoutKind.Explicit)]
public struct TestStruct
{
    [FieldOffset(0)]
    public byte byte1;
    [FieldOffset(1)]
    public byte byte2;
    [FieldOffset(2)]
    public byte byte3;
    [FieldOffset(3)]
    public byte byte4;
    [FieldOffset(4)]
    public byte byte5;
    [FieldOffset(5)]
    public byte byte6;
    [FieldOffset(6)]
    public byte byte7;
    [FieldOffset(7)]
    public byte byte8;

    [FieldOffset(0)]
    public double double1;
}

Затем он может быть обернут в такую ​​функцию (при условии, что у вас есть структура, определенная в вашем классе как частная переменная)

static string GetStringKey(double key)
{
    _conversionStruct.double1 = Double.MaxValue;

    return String.Format("{0}:{1}:{2}:{3}:{4}:{5}:{6}:{7}", 
        _conversionStruct.byte1,
        _conversionStruct.byte2, 
        _conversionStruct.byte3, 
        _conversionStruct.byte4, 
        _conversionStruct.byte5,
        _conversionStruct.byte6, 
        _conversionStruct.byte7, 
        _conversionStruct.byte8);
}

И используется вот так.

var s1 = GetStringKey(double.MaxValue);
var s2 = GetStringKey(double.MinValue);

, что дает ...

s1="255:255:255:255:255:255:239:127" 
s2="255:255:255:255:255:255:239:255"
2 голосов
/ 10 февраля 2012

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

Например, вы сохраняете элемент со значением ключа 1.01. Ваши вычисления приведут к 1.010000000000000123 и не будут соответствовать сохраненному ключу.

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

Кстати, использование типизированного словаря (т.е. Dictionary<double, string>) будет проще в использовании, чем HashTable.

0 голосов
/ 10 февраля 2012
  • Если можете, сделайте двойной длинным и используйте его в качестве ключа.(умножьте на 10, чтобы избавиться от десятичной точки)
  • Другой вариант, который не так хорош, как первый, - преобразовать значение типа double в строку.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...