Eu tenho uma lista vinculada:
MyLinkedList::LinkedList<Event *> list;
de onde LinkedList
vem desta biblioteca e Event
é esta estrutura:
typedef struct
{
TimeSpan time;
int value;
bool queued;
} Event;
de onde TimeSpan
vem esta biblioteca. Após preencher a lista com alguns itens executo a seguinte função:
bool Events::Save()
{
// order the elements by the time
_listEvents.sort(compare);
// open a file for writing
for (int i = 0; i < _listEvents.size(); i++)
{
Event *event = _listEvents.get(i);
// write the item to the file
writeEvent(file, *event);
}
file.close();
return true;
}
a compare
função é definida da seguinte forma:
int compare(Event *&ev1, Event *&ev2)
{
if (ev1->time.hours() > ev2->time.hours()) return true;
if (ev1->time.hours() < ev2->time.hours()) return false;
return (ev1->time.minutes() > ev2->time.minutes());
}
Apenas ordena os elementos pelo seu tempo. Este código funciona bem.
Agora preciso lidar com o queued
sinalizador na estrutura. Aqui está um exemplo de dados de entrada:
Tempo | Valor | Enfileiradas |
---|---|---|
18:00 | 1 | falso |
xx:xx | 2 | verdadeiro |
xx:xx | 3 | verdadeiro |
10h30 | 4 | falso |
xx:xx | 5 | verdadeiro |
08:15 | 6 | falso |
06:45 | 7 | falso |
Ao ordenar, os itens com o queued
sinalizador definido devem seguir o item anterior (com queued
não definido), independentemente do seu valor de tempo (daí o valor xx:xx
na tabela).
A saída esperada é:
Tempo | Valor | Enfileiradas |
---|---|---|
06:45 | 7 | falso |
08:15 | 6 | falso |
10h30 | 4 | falso |
xx:xx | 5 | verdadeiro |
18:00 | 1 | falso |
xx:xx | 2 | verdadeiro |
xx:xx | 3 | verdadeiro |
Em outras palavras: if queued
is false
os elementos serão ordenados normalmente (por seu tempo), if is true
eles devem seguir o elemento anterior (como se estivessem "agrupados" juntos).
Como a compare
função pode lidar apenas com dois itens e não tenho outras informações além do pedido inicial, como posso manter os queued
itens com o item “pai”?
Primeiro agrupe sua lista. No seu exemplo,
[1, 2, 3, 4, 5, 6, 7]
torna-se[[1, 2, 3], [4, 5], [6], [7]]
.Em seguida, classifique-os pelo carimbo de data/hora do primeiro elemento de cada grupo.
[[1, 2, 3], [4, 5], [6], [7]]
torna-se[[7], [6], [4, 5], [1, 2, 3]]
.Em seguida, nivele essa lista para obter
[7, 6, 4, 5, 1, 2, 3]
.Usando
std::vector
, isso pode ser algo como:Com saída: