Как сделать std::карта::найти функцию с учетом регистра?

#c #c 11 #find #stdmap #c -standard-library

Вопрос:

Я провел собеседование с компанией MNC. Он дал мне следующий код и попросил меня сделать find() функцию чувствительной к регистру. Я пытался, но не смог понять, как сделать встроенную функцию поиска чувствительной к регистру. Есть ли какой-либо способ сделать чувствительным к регистру поиск только определенного значения ключа?

 #include <iostream>
#include <map>
using namespace std;

int main()
{
    map<string, int> mp;
    mp["Test"] = 1;
    mp["test"] = 2;
    mp["TEST"] = 3;
    mp["tesT"] = 4;    

    for (auto it = mp.find("TEST"); it != mp.end(); it  )
    {
        cout << it->first << " " << it->second << endl;
    }

    return 0;
}
 

Выход :

 TEST 3
Test 1
tesT 4
test 2
 

Но я ожидаю, что результат будет:

 TEST 3
 

Комментарии:

1. В этом вопросе нет никакого смысла. Функция поиска уже учитывает регистр, и она находит только один элемент на карте. Вы выполняете итерацию с помощью итератора, возвращаемого функцией find, и, по сути, выполняете итерацию по всей вашей карте, но это не означает, что функция find не учитывает регистр. Попробуйте заменить элементы карты чем — либо другим TEST , кроме того, что начинается с Z -вы увидите тот же результат.

2. Краткая версия: вам не нужно перечислять до конца каждый итератор, который вы когда-либо получали из стандартного контейнера. Если то, что вы хотите, обнаружено, итератор будет ссылаться на это; если оно не найдено, итератор будет mp.end() . это действительно так просто. Я понятия не имею, почему вы используете цикл перечисления и какая сила на земле велела вам это сделать, но что бы это ни было / есть, это неправильно.

Ответ №1:

Проблема заключается в цикле for. Вам не нужно перебирать карту, чтобы распечатать ее. Скорее вам нужно сделать

 auto it = mp.find("TEST");
if (it != mp.end())
    std::cout << it->first << " " << it->second << std::endl;
 

std::map::find Будет найден итератор , указывающий на пару ключ-значение, у которой точно есть ключ "TEST" , если не найден только конечный итератор.

Ответ №2:

Здесь происходит то, что он находит «ТЕСТ», затем вы просматриваете оставшуюся часть карты и распечатываете все, что было после этого.

Как это бывает, в большинстве распространенных наборов символов буквы верхнего регистра сортируются перед строчными буквами, поэтому TEST это будет первый элемент в map . Поэтому, когда вы распечатываете вещи, начиная с этого момента, вы в конечном итоге распечатываете все предметы.

Но a map может содержать только один элемент с определенным ключом, поэтому нет реальной причины для повторения. Вы либо нашли один предмет ( it != container.end() ), либо нет ( it == container.end() ).

Если вы использовали a multimap , может быть несколько элементов с одним и тем же ключом. В этом случае вы, как правило std::equal_range , захотите найти все элементы с помощью этого одного ключа. Это вернет пару итераторов, один в начало диапазона, а другой в конец диапазона элементов с этим ключом. Затем вы распечатаете все товары в том диапазоне, который он вернул.