2015-12-06 3 views
1

Как вы можете видеть в моем коде, lenMap - это std::map с помощью функции сравнения . Эта функция просто проверяет длину строки.Как не использовать пользовательскую функцию сравнения std :: map в поиске (map :: find)?

Теперь, когда я хочу найти какой-либо ключ (используя map::find), карта по-прежнему использует эту функцию сравнения.

Но Как я могу заставить свою карту не использовать ее при поиске какого-либо ключа?

Код:

struct CompareByLength : public std::binary_function<string, string, bool> 
{ 
    bool operator()(const string& lhs, const string& rhs) const 
    { 
     return lhs.length() < rhs.length(); 
    } 
}; 

int main() 
{ 
    typedef map<string, string, CompareByLength> lenMap; 
    lenMap mymap; 

    mymap["one"] = "one"; 
    mymap["a"] = "a"; 
    mymap["foobar"] = "foobar"; 

    // Now In mymap: [a, one, foobar] 

    string target = "b"; 
    if (mymap.find(target) == mymap.end()) 
     cout << "Not Found :) !"; 
    else 
     cout << "Found :(!"; // I don't want to reach here because of "a" item ! 

    return 0; 
} 

ответ

1

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

Если вам нужно искать элементы по-другому, вы можете либо использовать алгоритм STL std::find_if() (который имеет линейную сложность по времени), либо создать вторую карту, которая использует другой сравнительный функтор.

В вашем конкретном примере, поскольку вам кажется, что вас интересует только длина строки, вы должны скорее использовать длину (типа std::size_t), а не строку как ключ.

Кстати, std::binary_function не нужен как базовый класс. Начиная с C++ 11, он даже устарел, например, см. here.

0

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

Либо хранить ваши строки в другую структуру данных, и сортировать их, или, возможно, попробовать эту функцию сравнения:

struct CompareByLength 
{ 
    bool operator()(const string& lhs, const string& rhs) const 
    { 
     if (lhs.length() < rhs.length()) 
     { 
      return true; 
     } 
     else if (rhs.length() < lhs.length()) 
     { 
      return false; 
     } 
     else 
     { 
      return lhs < rhs; 
     } 
    } 
}; 

Я не проверял, но я считаю, что это строки первого порядка по длине, и то, однако, строки обычно сравниваются.

Вы также можете использовать std::map<std::string::size_type, std::map<std::string, std::string>> и использовать длину для первой карты и строковое значение для второй карты. Вероятно, вы захотите обернуть это в класс, чтобы упростить его использование, так как нет защиты от беспорядка.

+0

Нет. Я действительно хочу заменить «b» на «a». поэтому моя пользовательская функция сравнения в порядке. моя проблема заключается в поиске фазы. – Emadpres

+0

Если вы замените «b» на «a», то почему вы ожидаете найти «b»? Это прошло. –

Смежные вопросы