2010-10-24 2 views
0

J'essaie de trouver le moyen le plus efficace, optimisé et le plus rapide de comparer aux vecteurs std de CString. les chaînes en question sont sensibles à la casse. J'ai essayé d'utiliser l'opérateur == pour le conteneur vectoriel mais cela retourne parfois des faux positifs. Je veux dire par exemple si un vecteur contient des éléments dans l'ordre (a, b, c) et l'autre les a dans l'ordre (b, c, a) l'opérateur == retournera faux même s'ils partagent les mêmes données. Une autre chose est qu'il ne fait pas de comparaison sensible à la casse.Quelle est la meilleure méthode pour comparer deux vecteurs de CString

J'ai pensé à utiliser une boucles imbriquées de base approche comme celle-ci:

//Not Tested 

BOOL bMatch = TRUE; 
for(int i=0; i<Vec1.size();i++) 
{ 
    if(!bMatch) 
    break; 
    int nComp=0; 
    for(int j=0;j<Vec2.size();j++) 
    { 
    if(vec1[i].CompareNoCase(Vec2[j])==0) 
     { 
      //We have a match--check next item 
      break; 
     } 
    else 
     { 
      nComp++; 
      if(nComp == Vec2.size()-1) 
      { 
       //Reached end of vector and no match found 
       //Vectors don't match 
       bMatch=FALSE; 
      } 
     } 

    } 
} 

Le code ci-dessus n'est pas testé et je ne sais pas s'il y a probablement une meilleure façon de parvenir à une telle comparaison, sans la nécessité de en utilisant des boucles imbriquées.

apprécierait des conseils ou de l'aide ...

+1

Veuillez définir "deux vecteurs de CString" - est-ce 'vecteur ', 'vecteur ', 'vecteur >' ou autre chose? Peut-être simple 'chaîne'? –

+1

@Tim: 'CString' est probablement la classe de chaînes MFC. –

+0

Je pense que c'est explicite ... mais juste pour être gentil son vecteur

Répondre

5

si un vecteur contient des éléments dans l'ordre (a, b, c) et l'autre les a dans l'ordre (b, c, a) l'opérateur == retournera false même pensé qu'ils partagent les mêmes données .

Insérez simplement les données dans deux conteneurs où l'ordre n'a pas d'importance et de comparer ceux-ci:

std::vector<CString> vec1; 
std::vector<CString> vec2; 

// ... 

std::multiset<CString> set1(vec1.begin(), vec1.end()); 
std::multiset<CString> set2(vec2.begin(), vec2.end()); 

bool equal_data = (set1 == set2); 

Si vous voulez ignorer le cas (que le code dans votre question semble suggérer), vous peuvent être paramétrées std::multiset et std::equal avec un comparateur approprié:

struct compareNoCase 
{ 
    bool operator()(const CString& a, const CString& b) 
    { 
     return a.CompareNoCase(b); 
    } 
}; 

std::vector<CString> vec1; 
std::vector<CString> vec2; 

// ... 

std::multiset<CString> set1(vec1.begin(), vec1.end(), compareNoCase()); 
std::multiset<CString> set2(vec2.begin(), vec2.end(), compareNoCase()); 

bool equal_data = std::equal(set1.begin(), set1.end(), 
          set2.begin(), 
          compareNoCase()); 

le paramétrage de std::multiset garantit que « bonjour » et « BONJOUR » dans la mêmes vecteur sont traités comme une seule valeur, et le paramétrage de std::equal garantit cela à travers les deux vecteurs. Enfin, si vous savez qu'aucun élément n'apparaît deux fois dans le même vector, vous pouvez utiliser set au lieu de multiset. Notez qu'il est probablement préférable de travailler avec un set ou multiset dès le début.

+0

Je crois que l'OP a dit de comparer les vecteurs de C-Strings. Dans ce cas, vous ne pouvez pas comparer deux ensembles de char * avec == et obtenir des résultats raisonnables. Mais l'OP peut avoir naturellement confondu la terminologie. –

+0

@Armen: Je ne suis pas certain de ce qu'un CString est censé être. J'attendrai le PO pour clarifier et ensuite changer mon poste si nécessaire. – fredoverflow

+0

@Red: Eh bien, voulez-vous que "bonjour" soit égal à "BONJOUR" ou pas? – fredoverflow

2

si (a, b, c) et (b, c, a) sont les mêmes pour vous, alors le vecteur est un mauvais choix, utilisez std::set ou std::multiset au lieu et, comme déjà dit, les comparer avec std::equal et passer strcmp comme argument de comparaison. Cette réponse est valide si, par CString, vous voulez dire des tableaux de caractères à terminaison nulle de type C. Si CString signifie MFC CString, la réponse de FredOverflow est parfaite.

0

Triez-les d'abord avec std :: sort, puis comparez-les avec std :: equal.

0

Ne pas utiliser simple pour boucle. Au lieu de cela, vous pouvez utiliser des itérateurs pour récupérer les éléments des deux vecteurs, puis comparer les valeurs en utilisant _tcscmp ou wcscmp.

Questions connexes