Если вы не возражаете против дополнительного пространства, попробуйте вставить элементы в map
.Всякий раз, когда вы найдете свой элемент на карте, вы можете напрямую сообщить об ошибке.
map<string, int> occurrences;
for (vector<string>::const_iterator cit = test.begin(); cit != test.end(); ++cit)
if ((++occurrences[*cit]) == 2)
cout << "ERROR"; // You can even signal which element is repeated here easily, using *cit.
Обратите внимание, что этот код правильно выдает сообщение только один раз для повторяющегося элемента (даже если элемент повторяется много раз),согласно умной поправке Тони Делрой .Хотя этот способ правильно подсчитывает вхождение каждой строки во всей коллекции (что может быть чем-то обязательным), этот путь может быть переполнен int
, если имеется 2 31 копий одного и того же элемента (илиБольше).Вместо этого вы можете использовать long long int
, если это так, и вы действительно хотите счетчик каждой строки.
Если вам не интересен счетчик каждой строки, еще более эффективный способ - использоватьset
, как предлагает smerlin (поскольку он поддерживает только строку, а не пару строк и int
, как map
), тем самым уменьшая требования к пространству ... и выдает сообщение об ошибкевсякий раз, когда вы находите предмет в наборе:
set<string> occurrences;
for (vector<string>::const_iterator cit = test.begin(); cit != test.end(); ++cit)
if (false == occurrences.insert(*cit).second)
cout << "ERROR"; // You can even signal which element is repeated here easily, using *cit.
Если вы хотите устранить проблему до того, как она возникнет, вставьте элементы в set
.Он автоматически удаляет дубликаты.Но позаботьтесь о том, чтобы элементы в set
были отсортированы, чтобы вы не сохранили порядок вставки.Если вы не возражаете, set
намного лучше, поскольку поиск в нем и чтение элементов в отсортированном порядке намного эффективнее.