为什么传入来自向量的整数在 make_pair 中不起作用?

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

提问人:Ann Flus 提问时间:10/28/2023 更新时间:10/28/2023 访问量:54

问:

对于我的生活,我无法弄清楚为什么这不起作用。

#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;
}

关键是返回第一个副本的位置,但make_pair从未完成其工作。我不知道为什么,但它不起作用,正如您通过测试输出所看到的那样,它永远不会将 ints[someint] 转换为布尔值为 true。然而,如果我将 a.at(i) 替换为整数,则输出符合预期。 这是怎么回事?你能不能不把 a.at(i)作为make_pair的论据??

C++ 矢量 映射

评论

1赞 Pepijn Kramer 10/28/2023
std::p air 是一种语义上无意义的类型,旨在用于模板(其中语义尚未知)。在所有其他情况下,只需声明一个包含您自己的两个成员的结构。通常也不需要按值传递向量。总而言之,你的代码看起来你仍在学习 C++(然后竞争性编码不是一个好的起点)。
1赞 Pepijn Kramer 10/28/2023
学习 C++ 的更好资源是一本好书(确保它是最新的,而不是教你“C”)。或者您可以使用 learncpp.com。此外,请确保检查 cppreference 以探索 C++ 必须提供的内容(容器/算法)。最后,请参阅 C++ 核心指南,了解如何使用 C++。
1赞 Pepijn Kramer 10/28/2023
确切的编译器错误是什么?我怀疑它是在警告你参考
1赞 user7860670 10/28/2023
map::operator[]不做你认为它做的事情。检查 的结果也是一个好主意。map::insert
1赞 Retired Ninja 10/28/2023
如果映射中尚不存在该键,则插入默认值为 (在本例中为)的键。然后失败,因为密钥已经存在。请改用该键来确定密钥是否已存在。如果你只想知道你以前是否看过这个数字,那么你应该用一个或来代替。ints[a.at(i)]falseinsertif(ints.find(a.at(i)) != ints.end())unordered_setset

答:

0赞 Alan Birtles 10/28/2023 #1
ints[a.at(i)]

如果尚不存在,将插入到地图中。falsea.at(i)

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

如果已存在,将无法插入到映射中。这意味着您永远不会将地图的任何元素设置为 。a.at(i)true

有几种方法可以解决这个问题。

insert返回一对迭代器和一个 bool,指示插入是否成功。您可以使用它来覆盖现有值:

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

不过,首先只使用运算符会更简单:[]

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

或者,您可以使用从不覆盖元素的事实在单个步骤中完成所有操作:insert

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

由于您在地图中存储的所有内容是一组可能更简单:true

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

评论

0赞 Ann Flus 10/28/2023
非常感谢您的解释。我对其他人说的话感到困扰。我正在尝试研究插入,我想知道,因为插入返回插入是否成功,如果 a[i] 已经存在,插入会返回 false,从而允许我们在这种情况下返回 i 值?
0赞 Alan Birtles 10/28/2023
是的,如果键已存在,则 insert 返回 false