为何从vector获取的整数传入make_pair无法正常工作?
问题分析与解决:map插入元素后访问始终返回false
你的代码核心问题不在于make_pair或vector::at,而是**std::map的operator[]行为特性**导致的:
问题根源
当你执行ints[a.at(i)](不管是在if判断还是后续打印)时,如果当前a.at(i)对应的key不存在于map中,map::operator[]会自动执行两个操作:
- 向map中插入一个以该key为键、值为对应类型默认值(
bool的默认值是false)的键值对 - 返回这个新插入值的引用
这就导致了你的代码逻辑出现矛盾:
- 第一次遇到某个key时,
if(ints[a.at(i)])会先自动插入一个false值 - 随后你调用
ints.insert(make_pair(a.at(i), true)),但因为map中已经存在该key(刚才operator[]插的),insert操作会直接失败,true根本没被插入 - 最后打印
ints[a.at(i)]时,访问的是之前operator[]插入的那个false,看起来就像make_pair没生效
解决方案
要避免operator[]的自动插入行为,改用map::find来检查key是否存在:
方案1:用find检查 + operator[]赋值
int solution(vector<int> a) { map<int, bool> ints; for(int i = 0; i < a.size(); i++) { if (ints.find(a.at(i)) != ints.end()) { return i; } ints[a.at(i)] = true; // 直接赋值,覆盖或插入新键值对 cout << a.at(i) << " " << ints[a.at(i)] << endl; } return -1; }
方案2:用find检查 + insert插入
int solution(vector<int> a) { map<int, bool> ints; for(int i = 0; i < a.size(); i++) { auto it = ints.find(a.at(i)); if (it != ints.end()) { return i; } auto [insert_it, success] = ints.insert(make_pair(a.at(i), true)); // C++17及以上 // 若用旧标准,可写成pair<map<int,bool>::iterator, bool> result = ints.insert(...); cout << a.at(i) << " " << insert_it->second << endl; } return -1; }
补充说明
你提到“将a.at(i)替换为直接传入整数结果符合预期”,其实这只是巧合——如果传入的整数之前已经被正确插入到map中,operator[]会直接返回已有的值;但如果是新整数,同样会触发自动插入false的问题,只是你测试的场景没覆盖到而已。
修正后的完整代码
#include <iostream> #include <vector> #include <map> using namespace std; int solution(vector<int> a) { map<int, bool> ints; for(int i = 0; i < a.size(); i++) { auto it = ints.find(a.at(i)); if(it != ints.end()) { return i; } ints.insert({a.at(i), true}); // 也可以用emplace(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}; cout << "第一个重复元素的位置:" << solution(a) << endl; return 0; }
内容的提问来源于stack exchange,提问作者Ann Flus
相关产品推荐
相关产品推荐

