построение большой многомерной векторной матрицы - PullRequest
1 голос
/ 28 февраля 2011

Прямо сейчас у меня есть вектор std::vector<char> myVector(4), содержащий любую комбинацию набора символов. Допустим, {@, #, O, *,%, $ ,!} может быть больше или меньше, но не намного больше этого, может не всегда 4 члена, но будет постоянным для любого экземпляра одного экземпляра.

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

в псевдокоде, который я пытаюсь выполнить:

SomeDataStructure['*']['#']['@']['O'] = someData

(someData будет небольшим классом, но это не должно иметь значения)

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

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


редактирование:

Я решил это, используя карту:

std::map<std::vector<char>, someData> myMap;

Ответы [ 3 ]

0 голосов
/ 28 февраля 2011

В C ++ char - это число (обычно 8-битное число).Таким образом, вы можете теоретически создать 4-D массив с индексами.Очевидная проблема, связанная с этим, состоит в том, что при индексировании всего 4 байта ваш массив заканчивается 2 32 записями.Например, если someData занимает 32 бита, массив будет занимать около 16 гигабайт (из которых, по-видимому, будет использоваться только незначительный процент).

Очевидной альтернативой будет объединениеотдельные символы вместе в строку, и используйте это в качестве ключа для карты:

std::map<std::string, SomeData_t> mymap;

mymap["*#@O"] = someData;

В зависимости от того, как часто вы вставляете или смотрите элементы поиска, вы можете вместо этого использовать unordered_map.Обычно это дает немного более быстрый поиск в обмен на немного более медленную вставку.

0 голосов
/ 28 февраля 2011

Поскольку количество возможных символов ограничено до 8, вы можете использовать перечисление.Следовательно, вам нужно всего 3 бита для представления каждого «символа».Вы можете упаковать несколько этих 3-битных «символов» в короткое целое число, используя bitfields .Полученное упакованное целое число становится индексом вашего vector<SomeData>.

Пространство, занятое этим вектором, будет space_of_SomeData * 2^(3*number_of_spaces).Если, например, number_of_spaces равно 4, это приводит к 4096*space_of_SomeData.Это может привести к некоторой потере памяти, но поиск и вставка должны быть очень быстрыми.

Вот пример кода:

#include <vector>

enum CharSet
{
    ampersand,
    pound,
    letterOh,
    percent,
    dollar,
    exclamation
};

struct CompositeIndex
{
    union
    {
        struct // Bitfield
        {
            unsigned c0 : 3; // 3 bits
            unsigned c1 : 3; // 3 bits
            unsigned c2 : 3; // 3 bits
            unsigned c3 : 3; // 3 bits
        } chars;

        unsigned int index;
    };
};

unsigned int lookup(CharSet c0, CharSet c1, CharSet c2, CharSet c3)
{
    CompositeIndex ci;
    ci.chars.c0 = c0;
    ci.chars.c1 = c1;
    ci.chars.c2 = c2;
    ci.chars.c3 = c3;
    return ci.index;
}

typedef int SomeClass;

int main(int argc, char* argv[])
{
    std::vector<SomeClass> vec(100);
    vec[lookup(ampersand, percent, dollar, pound)] = 42;
}

Если вам абсолютно необходимо работать с char символами, выможет легко создать таблицу поиска из 256 элементов, которая быстро преобразует символы 'char' в CharSet значения.


Как уже обсуждалось другими, вы можете использовать std::map<std::string, SomeData> или даже (возможно, быстрее) std::map<char[4], SomeData, Comparitor>.Если приблизительное распределение частот различных последовательностей символов известно, попробуйте сначала вставить наиболее частые шаблоны в карту.В зависимости от внутренней реализации карты это может ускорить поиск наиболее частых шаблонов (они находятся в верхней части базового дерева двоичного поиска).

0 голосов
/ 28 февраля 2011

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

Взгляните на карту класса - он должен соответствовать вашим потребностям.

...