У меня есть список из 100 несортированных предметов. Каждый элемент принадлежит к группе. Группа, к которой принадлежит элемент, является просто членом класса элемента.
Используя C / C++, я ищу наиболее эффективный способ сканирования списка элементов, проверки того, в какой группе они находятся, и вывода элемента на экран. Но вот в чем загвоздка. После того, как элемент из группы был напечатан на экране, я не хочу больше печатать элементы, принадлежащие этой группе.
Я использую предварительный компилятор STL, и размер исполняемого файла имеет решающее значение, поэтому я не хочу начинать определять свои собственные классы Hash.





Вы можете создать словарь / хэш-карту групп и для каждой группы сохранить логическое значение, указывающее, был ли напечатан элемент этой группы или нет.
Образец кода:
#include <unordered_map>
#include <string>
#include <iostream>
std::string getGroupForNumber( int num )
{
//
}
int main()
{
typedef std::tr1::unordered_map< std::string, bool > hashmap;
hashmap groupsPrinted;
for( int i = 0 ; i < 100 ; ++i ) {
if ( groupsPrinted[ getGroupForNumber( i ) ] == false ) {
groupsPrinted[ getGroupForNumber( i ) ] = true;
std::cout << i << std::endl;
}
}
return 0;
}
Спасибо, я подумал об этом, но проблема в том, что я использую предварительный компилятор STL, что означает, что мне нужно создать свой собственный хэш-класс. Это то, чего я хочу избежать из-за нехватки места.
Отсортируйте элементы по значению группы (если это указатель, вы можете использовать его адрес, в противном случае лексикографический сортирует нить). Затем прокрутите этот отсортированный список, всегда беря первый элемент каждой группы.
Это занимает примерно
n + n * log(n)
Я думаю, что это разумная альтернатива между размером исполняемого файла и скоростью.
Поскольку n всего около 100, этот компромисс вполне разумен; нет причин использовать сложную структуру данных для такого небольшого размера проблемы.
Если вы можете пронумеровать группы 0..99, вам понадобится массив логических значений или битовый набор, если вы хотите оптимизировать. Инициализировать весь массив как «false». Установите arr [groupId] = 'true' после его печати и проверьте значение в следующий раз перед печатью. STL не требуется.
Сохраните std :: set имен групп, элементы которых больше не должны печататься.
Вы написали c / C++ в вопросе, поэтому вот код c. У меня есть пара вопросов. Можно ли когда-нибудь в будущем распечатать группу? Список элементов статичен? Имеет ли значение, какой элемент из определенной группы вы печатаете?
Я бы предложил следующую конструкцию (с моим ограниченным пониманием проблемы):
Массив списков.
typedef struct node{
void *item; /* this is your item */
node *next;
} node_t;
typedef struct {
node_t *my_group;
int used;
} group_t;
static group_t my_items[NUM_OF_GROUPS]; /* this is your ordered by groups list.*/
А еще лучше использовать список списков. group_t будет:
typedef struct group{
node_t *my_group;
group *next_free;
} group_t;
Чтобы ответить еще на несколько вопросов.
Is the item list static?
Нет, он может уменьшиться или увеличиться в любой момент.
Does it matter which item from a specific group you print?
Пока нет, нет. Может быть, в будущем, но на данный момент должно быть достаточно напечатать первый найденный элемент, принадлежащий к уникальной группе.
А как насчет групп? ты можешь получить новую группу? И может ли группа стать актуальной после того, как вы напечатаете одного из ее участников?
Стоимость печати на экране на несколько порядков больше, чем что-либо еще, что вы можете сделать с объектами. Если у вас есть массив из 10 миллионов объектов всего в нескольких группах, то сортировка не является разумным вариантом. Если группы можно идентифицировать по статическому индексу (т. Е. Целому числу в заданном диапазоне), просто используйте массив масок, чтобы указать, видели ли они. Если группы более сложные, вы можете сохранить просмотренные группы в любой заданной структуре данных (хэш, дерево и т. д.).
Вам необходимо предоставить дополнительную информацию. Ваш список товаров отсортирован? Что составляет связь между элементом и группой? Это просто член std :: string, называющий группу?