Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> STL Добавление в отсортированный массив 
V
    Опции темы
roko
Дата 7.2.2010, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 2.3.2008

Репутация: нет
Всего: нет



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

Код

char* p1="that";
char* p2="alpha";
char* p3="color";
char* p4="despite";
char* p5="alpha";

после добавления указателя p1, массив будет содержать p1
после добавления  p2 - p2, p1
после добавления  p3 - p2, p3, p1
после добавления  p4 - p2, p3, p4, p1
после добавления  p5 - p2, p3, p4, p1 (так как такое слово уже есть)

потом надо будет обращаться к указателям последовательно, чтобы сохранить строки в файл.
Строк много(~100000), поэтому хочется чтобы вставка указателя в массив происходила быстро. Тоесть, по возможности, чтобы определение того, есть ли такое слово в массиве, было не через линейный поиск, а, скажем, через двоичный поиск.
Хочется использовать STL, но не знаю как это сделать.
Что лучше использовать arrayvector или еще что-то?
Функцию добавления, в этом случае, самому писать или такая уже есть?
по возможности, привести кусок кода или написать что за чем делать на словах.
PM MAIL   Вверх
Ozerich
Дата 7.2.2010, 22:40 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 2.8.2009
Где: Минск, Беларусь

Репутация: нет
Всего: 5



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

Это сообщение отредактировал(а) Ozerich - 7.2.2010, 22:42
--------------------
C++(STL) / DHTML(CSS) / Javascript / PHP  Developer
PM MAIL ICQ Skype   Вверх
roko
Дата 7.2.2010, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 2.3.2008

Репутация: нет
Всего: нет



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

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

Это сообщение отредактировал(а) roko - 7.2.2010, 23:03
PM MAIL   Вверх
BEOWOLF
Дата 7.2.2010, 23:07 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 24.8.2007

Репутация: нет
Всего: 2



Есть ещё std::set и std::map, в них данные - отсортированы, и поиск происходит по двоичному дереву. Насчёт хэша - это тоже хорошая мысль, в качестве хэш-функции лучше всего использовать CRC-код, 16-битный или 32-битный, вот пример вычисления:
Код

#define DO1 crc = table[(unsigned char)(crc) ^ *data++] ^ (crc >> 8)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1

static CRC32 _CRC32(const unsigned char* data, size_t len, CRC32 crc, const CRC32* table)
{
    if (!data) return crc;

    while (len >= 8) {
        DO8;
        len -= 8;
    }
    while (len--) {
        DO1;
    }
    return crc;
}

CRC32 CRC32IEEE(const void* data, size_t len, CRC32 crc)
{
    static CRC32 table[256];
    static const watchdog wd(0xEDB88320, table);

    return _CRC32((const unsigned char*)data, len, crc, table);
}


Добавлено через 9 минут и 18 секунд
да, ещё одну фичу не дописал для инициализации таблицы:
Код

struct watchdog {
    watchdog(const CRC32 CRC_POLY, CRC32* table) {
        unsigned i, j;
        unsigned r;
        for (i = 0; i < 256; i++){
            for (r = i, j = 8; j; j--)
                if (r & 1) r = (r >> 1) ^ CRC_POLY;
                else r >>= 1;
                table[i] = r;
        }
    };
};

Кстати, CRC можно вычислять через статическую таблицу, в инете полно примеров. Ну и кроме того, зачастую намного удобнее и быстрее работать с CRC от строк, чем с самими строками.
PM MAIL   Вверх
roko
Дата 8.2.2010, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 2.3.2008

Репутация: нет
Всего: нет



BEOWOLF, можете объяснить что делает второй define? Я такого раньше не встречал.
Насколько я понял, функция CRC32IEEE просто возвращает crc(или хеш) для data.
Мне нужно чтобы crc хранились так, чтобы когда я буду последовательно, от начала до конца, перебирать crc, то автоматически должны будут перебираться соответствующие строки в алфавитном порядке, которые я буду сохранять в файл. (изначально строки не в алфавитном порядке)
Объясните на словах причем здесь хеш.(что такое хеш таблица мне извесно, но неясно как вы хотите ее здесь применить.)

Это сообщение отредактировал(а) roko - 8.2.2010, 00:23
PM MAIL   Вверх
NewDima
Дата 8.2.2010, 08:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 922
Регистрация: 20.2.2006
Где: <?here?>

Репутация: нет
Всего: 12



Цитата

что делает второй define?

восемь раз повторяет первый.
BEOWOLF имел ввиду, что в хеш таблицу ты будешь загонять значения (сами строки) по ключу (хеш строки)
таким образом, когда ты будешь заносить новое значение:
Код

CRC32 crc32(char *buffer) {...}
...
    char *u[] = {
        "that"
      , "alpha"
      , "color"
      , "despite"
      , "alpha"
    };
    std::map<CRC32, std::string> map;
    for (char *string = u[0]; string < u[sizeof(u)/sizeof(u[0])]; ++string) {
        map[crc32(string)] = string;
    }

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

Это сообщение отредактировал(а) NewDima - 8.2.2010, 08:39
PM ICQ   Вверх
maxim1000
Дата 8.2.2010, 09:15 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



про хеш можно забыть, т.к. нужна отсортированность, а порядок хеш-функции не сохраняют

так что лучше просто использовать std::set - он придуман как раз для этого



--------------------
qqq
PM WWW   Вверх
roko
Дата 8.2.2010, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 2.3.2008

Репутация: нет
Всего: нет



NewDima, спасибо за объяснение.
maxim1000, так и сделаю.
Всем спасибо, вопрос решен.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0716 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.