На самом деле довольно легко объяснить, что происходит, если вы понимаете, что целое число 0
преобразуется в логическое значение false
(и все ненулевое значение равно true
), и как ранжируется for
цикл работы .
Если мы начнем с первого цикла:
for(int i = 0;i < s.size();i++){
if(!map[s[i]]){
cout<<s[i];
map[s[i]] = i;
}
}
Здесь переменная i
представляет индекс символы в строке. Индексы будут (по порядку) 0
, 1
и 2
.
. На первой итерации 'd'
не существует, поэтому map[s[i]]
создаст элемент снулевое значение и вернуть нулевое значение. Это делает условие равным !0
, которое является истинным, поэтому вы печатаете символ, а затем назначаете индекс 0
на map['d']
(который уже равен 0
).
Вторая итерация такая же, но вы присваиваете значение 1
map['v']
.
Затем вы попадаете на третью итерацию, где map['d']
уже существует. Но , поскольку значение равно 0
ваше состояние считает, что оно не существует.
Таким образом, ваше состояние имеет недостатки. Чтобы проверить, не существует ли ключ, используйте count
if (map.count(s[i]) == 0)
Или вы можете использовать find
if (map.find(s[i]) == map.end())
Или когда приходит C ++ 20, вы можете использовать contains
if (map.contains(s[i]))
Затем второй цикл:
for(auto i :s){
if(!map[i]){
cout<<i<<" ";
map[i] = i;
}
}
Здесь i
это не индекс, это символ . Таким образом, значения, которые вы назначаете элементам карты с map[i] = i
, не будут 0
, 1
или 2
, это будут значения закодированных символов, которые для ASCII будут 100
для символа 'd'
и118
для 'v'
.
Таким образом, на первой итерации map[i]
будет равно нулю (как и раньше), но затем вы присваиваете 100
этому элементу.
Во второйитерация такая же, но вы присваиваете значение 118
.
Теперь мы возвращаемся к букве 'd'
со значением 100
. Когда вы проверяете map['d']
во второй раз, значение не равно нулю, и у вас есть !100
, что составляет false
.