Каков наилучший метод для сравнения двух векторов CString? - PullRequest
0 голосов
/ 24 октября 2010

Я пытаюсь найти наиболее эффективный, оптимизированный и быстрый способ сравнения с стандартными векторами CString. рассматриваемые строки чувствительны к регистру. Я пытался использовать оператор == для векторного контейнера, но это иногда возвращает ложные срабатывания. Я имею в виду, например, если один вектор содержит элементы в порядке (a, b, c), а другой - в порядке (b, c, a), оператор == вернет false, даже если они совместно используют одни и те же данные. Другое дело, что он не делает сравнения с учетом регистра.

Я думал об использовании базового подхода с вложенными циклами, подобного этому:

//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;
             }
        }

  }
}

Приведенный выше код не тестировался, и я не уверен, что, возможно, существует лучший способ добиться такого сравнения без необходимости использования вложенных циклов.

Буду признателен за любой совет или помощь ...

Ответы [ 4 ]

5 голосов
/ 24 октября 2010

если один вектор содержит элементы в порядке (a, b, c), а другой - в порядке (b, c, a), оператор == вернет false, даже если они совместно используют одни и те же данные.

Просто вставьте данные в два контейнера, где порядок не имеет значения, и сравните их:

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);

Если вы хотите игнорировать регистр (который, по-видимому, предлагает код в вашем вопросе), вы можете параметризовать std::multiset и std::equal с помощью соответствующего компаратора:

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());

Параметризация std::multiset гарантирует, что "привет" и "HELLO" в одном и том же векторе будут рассматриваться как одно значение, а параметризация std::equal гарантирует это для двух векторов.

И, наконец, если вы знаете, что ни один элемент не встречается дважды в одном и том же vector, вы можете использовать set вместо multiset. Обратите внимание, что, вероятно, лучше работать с set или multiset с самого начала.

2 голосов
/ 24 октября 2010

если (a, b, c) и (b, c, a) одинаковы для вас, то вектор - плохой выбор, вместо этого используйте std::set или std::multiset и, как уже было сказано, сравните их сstd::equal и передайте strcmp в качестве аргумента компаратора.Этот ответ действителен, если под CString вы имеете в виду массивы символов с нулевым символом в конце в стиле C.Если CString означает MFC CString, ответ FredOverflow является идеальным.

0 голосов
/ 26 октября 2010

Не используйте простой цикл. Вместо этого вы можете использовать итераторы для извлечения элементов из обоих векторов, а затем сравнивать значения, используя _tcscmp или wcscmp.

0 голосов
/ 24 октября 2010

Сортируйте их сначала с помощью std :: sort, затем сравните их с std :: equal.

...