c++vectormaps

Why does passing in an integer that's from a vector not work in make_pair?

For the life of me I cannot figure out why this doesn't work.

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

int solution(vector<int> a) {
map<int, bool> ints;
int b;
for(int i = 0; i < a.size(); i++) {
if(ints[a.at(i)]) {
return i;
}
else {
ints.insert(make_pair((a.at(i)), true));
cout << a.at(i) << " " << ints[a.at(i)] << endl;
}
}
return -1;
}

int main() {
vector<int> a = {2, 1, 3, 5, 3, 2};
solution(a);

return 0;
}
``````

The point is to return the location of the first duplicate, yet the make_pair is never doing its job. I don't know why but it is not working, as you can see by testing the output it is never turning ints[someint] to have a boolean value of true. Yet if I replace a.at(i) with an integer then the output is as expected. What is going on? Can you not pass a.at(i) as an argument for make_pair??

Solution

• ``````ints[a.at(i)]
``````

Will insert `false` into the map if `a.at(i)` doesn't already exist.

``````ints.insert(make_pair((a.at(i)), true)
``````

Will fail to insert into the map if `a.at(i)` already exists. This means that you never set any elements of the map to `true`.

There are a few options to solve this.

`insert` returns a pair of an iterator and a bool indicating whether the insert was successful. You can use this to overwrite the existing value:

``````auto result = ints.insert(make_pair((a.at(i)), true);
if (!result.second)
{
*result.first = true;
}
``````

It's simpler though to just use the `[]` operator in the first place:

``````ints[a.at(i)] = true;
``````

Alternatively you can use the fact that `insert` never overwrites the element to do everything in a single step:

``````for(int i = 0; i < a.size(); i++)
{
auto result = ints.insert({a[i], true});
if (!result.second) return i;
}
``````

As all you're ever storing in the map is `true` a set might be simpler:

``````std::set<int> ints;
for(int i = 0; i < a.size(); i++)
{
auto result = ints.insert(a[i]);
if (!result.second) return i;
}
``````