2010-06-07 8 views
6

Ho un viz struct:Qt e trovare le corrispondenze parziali in un QList

struct NameKey 
{ 
    std::string  fullName; 
    std::string  probeName; 
    std::string  format; 
    std::string  source; 
} 

che si tengono in un QList:

QList<NameKey> keyList; 

quello che devo fare è trovare un'occorrenza in keylist di una corrispondenza parziale in cui la ricerca riguarda un NameKey che ha solo due membri pieni. Tutte le voci della keylist sono complete di NameKey.

La mia attuale implementazione è, beh, noiosa all'estremo con troppe if e condizioni.

Quindi, se ho un DataKey con un fullName e un formato ho bisogno di trovare tutte le occorrenze in keyList che corrispondono. Qualche utile Qt/boost disponibile?

risposta

3

QList è compatibile con STL. Così si può utilizzare con l'algoritmo STL:

struct NameKeyMatch { 
    NameKeyMatch(const std::string & s1, const std::string & s2, const std::string & s3, const std::string & s4) 
    : fullName(s1), probeName(s2), format(s3), source(s4) {} 

    bool operator()(const NameKey & x) const 
    { 
     return fullName.size() && x.fullName == fullName && 
       probeName.size && x.probeName == probeName && 
       format.size && x.format == format && 
       source.size && x.source == source; 
    } 

    std::string fullName; 
    std::string probeName; 
    std::string format; 
    std::string source; 
}; 

QList<int>::iterator i = std::find_if(keyList.begin(), keyList.end(), NameKeyMatch("Full Name", "", "Format", "")); 

Non so se Qt manterrà attivamente compatibilità STL però.

+0

Beh, questo sembra fantastico! Grazie. – ExpatEgghead

+0

la mia sembra un po 'diversa. return! (FullName.size() && x.fullName.compare (fullName)) && ! (ProbeName.size() && x.probeName.compare (probeName)) && ! (Format.size() && x. format.compare (formato)) && ! (source.size() && x.source.compare (source)); – ExpatEgghead

4

Solo una nota: qualsiasi soluzione che utilizza un elenco ha una complessità di tempo O (n), almeno.

Un'opzione è utilizzare QString, anziché std::string e usufruire del supporto integrato di espressioni regolari.

Esempio:

#include <QList> 
#include <QString> 
#include <QRegExp> 

struct NameKey 
{ 
    QString fullName; 
    QString probeName; 
    QString format; 
    QString source; 
}; 

QList<NameKey> keyList; // <-- 

void Foo() { 
    QRegExp reg("pattern"); // <-- prepare a regular expression (format) 
    NameKey nk; 
    foreach (nk, keyList) { 
     if (nk.fullName.contains(reg)) { 
     // a match ... 
     break; 
     } 
     // ... 
    } 
} 
+0

@Nick D: Si potrebbe voler chiarire che qualsiasi soluzione a questo problema utilizzando un elenco avrà almeno una (almeno) complessità temporale. In altri casi questo non è vero. –

+0

@Adam, se memorizziamo i record NameKey in un contenitore di elenchi, non abbiamo alcuna opzione eccetto il iterare su quell'elenco mentre cerchiamo le corrispondenze. A meno che non usiamo un contenitore ausiliario, ad esempio una mappa o Trie, per memorizzare informazioni extra per accelerare la ricerca non vedo un modo più veloce per implementarlo. Ho dimenticato qualcosa? –

+0

@Nick D: Un esempio è se l'elenco è ordinato è possibile utilizzare una ricerca binaria e ottenere O (log n). O come hai detto tu, se c'è una struttura di indice per accelerare la ricerca. –

0

Simile a Nick D's answer:

#include <QList> 
#include <QString> 
#include <QRegExp> 

struct NameKey 
{ 
    QString fullName; 
    QString probeName; 
    QString format; 
    QString source; 

    bool containsPattern(const QRegExp &pattern) { 
     return fullName.contains(reg) || 
       probeName.contains(reg) || 
       format.contains(reg) || 
       source.contains(reg); 
    } 
}; 

QList<NameKey> matches(const QList<NameKey> &keyList, const QString &pattern) { 
    QRegExp reg(pattern); 
    QList<NameKey> matches; 
    foreach (NameKey nk, keyList) { 
     if (nk.containsPattern(reg)) 
     matches << nk; 
    } 
    return matches; 
} 

Ci sono ovviamente molti modi per farlo. Mi piace mettere più informazioni possibili nelle strutture dati.

+0

Fastidiosamente non riesco a cambiare NameKey. – ExpatEgghead

Problemi correlati