найти несколько значений в unordered_set используя find

Я хочу использовать указанную функцию equal_to int unordered_set
Пример кода нравится это:

struct myEqual
{       //string with one different character is considered equal
bool operator()(const string &s1, const string &s2)const
{

if(s1.length() != s2.length()) return false;
int dis = 0;
for(unsigned int i = 0; i<s1.size(); i++)
{
if(s1[i] != s2[i])
{
dis++;
if(dis >= 2) return false;
}
}
return true;
}
};

int main()
{
unordered_set<string, std::tr1::hash<string>, myEqual> myDict;
myDict.insert("a");
myDict.insert("b");
myDict.insert("c");

unordered_set<string, std::tr1::hash<string>, myEqual>::iterator it = myDict.find("k");
if(it == myDict.end())
{
cout<<"myequal not work"<<endl;
}
else
{
cout<<*it<<endl;
}
return 0;
}

согласно функции myEqual, есть три значения «a», «b», «c», которые «равны» к «k», однако находка возвращает только один итератор.
Есть ли в любом случае найти все равные значения?

1

Решение

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

  1. поскольку "a", "b" а также "c" все сравниваются равными друг с другом, вы можете оставить только один из них в unordered_set,
  2. У вас есть элементы, которые сравниваются одинаково, но, вероятно, имеют разные хэш-коды. Это нарушает контракт, который вы должны выполнить, чтобы неупорядоченный набор работал правильно.

Более общая проблема, которую следует иметь в виду, заключается в том, что ваши отношения эквивалентности не являются переходными: "aa" равняется "ab", а также "ab" равняется "bb", Еще "aa" не равно "bb",

4

Другие решения

Наилучшим подходом было бы исправить следующие 4 вещи

  1. Используйте std:unordered_multiset как контейнер

  2. Использовать взаимно согласованные хэш-функция и функция сравнения ключей. В частности, хеш-функция должна отображать равные элементы на равные ключи.

  3. Используйте функцию сравнения, которая является отношение эквивалентности. В частности, это означает, что если A==B а также B==C, затем A==C, где == соответствует вашему myEqual,

  4. Используйте функцию-член equal_range который возвращает пару итераторов. Если
    первый итератор не равен концу вашего контейнера, вы можете цикл.

Код:

auto res = myDict.equal_range("k");
if(res.first == myDict.end())
{
cout<<"myequal not work"<<endl;
}
else
{
for (auto it = res.first; it != res.second; ++it)
cout<<*it<<endl;
}

Ваша хэш-функция и оператор сравнения в настоящее время нарушают требования к контейнерам стандартной библиотеки C ++. Ваш хэш-код не соответствует (в смысле вашего myEqual) строки для равных ключей хеша. Ваш оператор сравнения не транзитивен (см. Пример @NPE). Это означает, что вы не можете использовать std::unordered_set или же std::unordered_multiset, Если вы сделаете это, ваш код выдаст неопределенное поведение.

0

По вопросам рекламы [email protected]