Sto sviluppando un programma in cui due volte ho trovato la soluzione a un problema era usare le tabelle hash con iteratori come chiavi e qualche altro tipo arbitrario come valore.
Mi sono ritrovato a utilizzare questo modello inizialmente per gestire due strutture di dati che si influenzano a vicenda, ma che non sono accoppiate a sé stanti. In questo primo istante avevo una GUI creata in QT in cui desideravo che l'interazione dell'utente influisse su una struttura dati sottostante. In questo caso c'era una lista collegata all'interno di un altro oggetto che doveva essere modificato quando l'utente rimuoveva o aggiungeva elementi a una rappresentazione della GUI di quell'oggetto (che era una lista).
Non ho molta esperienza nella programmazione della GUI, quindi la mia soluzione era quella di inviare segnali all'oggetto incapsulante sull'utente cancellando l'elemento corrispondente nella GUI con informazioni su quale elemento della GUI era stato cancellato. internamente l'oggetto incapsulante prende queste informazioni dal segnale (l'informazione è un iteratore) e le associa ad un altro iteratore che viene poi rimosso dalla lista collegata (o in modo simile è inserito un nuovo elemento). Per evitare l'accoppiamento tra la GUI e l'elaborazione del mio programma, ho creato una nuova classe che era un oggetto di configurazione che genera l'effettiva classe principale utilizzata nell'elaborazione dopo che sono state eseguite determinate azioni.
Sembrava una soluzione piuttosto disgustosa al problema, ma non riuscivo a capire come migliorarlo, l'azione di Gui sembra avere bisogno di una correlazione diretta con l'azione non gui.
Recentemente mi sono ritrovato a usare di nuovo uno schema simile, stavolta stavo cercando di implementare quanto segue:
Ho due elenchi di elementi (vecchi e nuovi) ai quali posso applicare una metrica di distanza. Voglio associare elementi da una lista con elementi nel secondo. Non voglio utilizzare l'algoritmo ungherese a causa della complessità del codice e del runtime dell'algoritmo.
Stavo pianificando di implementare l'associazione trovando l'elemento con la minima distanza dal nuovo elemento, confrontandolo con il precedente valore più piccolo associato a quell'elemento, quindi sostituendo il valore associato fino a quando ogni elemento è stato ripetuto con iterazione in nuovo.
Il problema è che, se non voglio semplicemente taggare un nuovo valore non necessario a questi elementi (cioè last_smallest_distance
e current_closest_associated_item
) che non hanno alcun valore dopo il passo di associazione. Dovrò trovare un modo per aggiungere persistenza tra le iterazioni utilizzate per trovare l'associazione. La soluzione più ovvia per me è ancora una volta creare una tabella hash iteratore in cui ogni iteratore è associato a una distanza minima separata e alla coppia di valore associata più vicina corrente.
Ecco un esempio di ciò di cui sto parlando:
struct ItemDistancePair{
Item & item;
double distance;
}
void updateOldItems(std::list<Item>& old_items, const std::list<Item>& new_items){
std::unordered_map<std::list<Item>::iterator, ItemDistancePair) old_new_value_map;
for(auto& new_item: new_items){
std::list<Item>::iterator closest_old_itr = findClosestAssociation(new_item, old_items)
double distance = new_item.distanceFrom(*closest_old_itr);
auto map_location_itr = old_new_value_map.find(closest_old_itr);
if(map_location_itr == old_new_value_map.end()){
old_new_value_map.insert(std::make_pair(closest_old_itr, ItemDistancePair(new_item, distance)));
}
else if(map_location_itr->second.distance > distance){
map_location_itr->second = ItemDistancePair(new_item, distance);
}
}
for(auto& key_value_pair : old_new_value_map){
key_value_pair.first->updateItem(key_value_pair->second.item);
}
}
Si noti che nel caso in cui più elementi nuovi siano più vicini a un vecchio articolo, è possibile che un altro vecchio oggetto non venga mai aggiornato, questo va bene
Come puoi vedere, questo non è l'ideale (anche se forse questo non sarebbe un problema in una lingua diversa dal C ++?) causa un sacco di codice strano (mi costringe a fare una struct se non lo faccio voglio usare std :: pair).
È accettabile o c'è un modo per aggirare questo, o è la vera soluzione migliore al problema solo per includere queste informazioni sulla distanza nella classe Item
stessa, cosa stavo cercando di evitare in primo luogo?