0

我想在列表中查找特定元素。如果没有找到我想要一个特定的值,比如返回 -1。如何为此使用 std::find() ?

我在这里读到find() 将迭代器返回到范围 [first,last) 中比较等于 val 的第一个元素。如果没有找到这样的元素,则函数最后返回。

但这导致了一个模棱两可的情况:

例如:

如果列表是

0 -> 1 -> 2 -> 3

当我使用

vector<int> v(4);
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
vector<int>::iterator i;

i = find(v.begin(), v.end(), 4);
//Unsuccessful find, so I want a value, say -1.
cout<<*i<<endl;  //this prints zero during an unsuccessful search

i = find(v.begin(), v.end(), 0);
cout<<*i<<endl;  //this too prints zero which is ambiguous
//because zero was already in my list

如何摆脱这种模棱两可的局面?

4

3 回答 3

4

您的第一个调用find是返回过去的迭代器。您不能取消引用此迭代器。您有未定义的行为,因为您正在使用cout<<*i<<endl;. 它打印 0 的事实是无关紧要的。

它不会给出模棱两可的情况,因为如果失败,它会返回第二个参数的副本。在这种情况下,它返回v.end(). 您应该检查是否std::find成功:

if (i != v.end()) {
  cout<<*i<<endl;
}
于 2013-04-09T18:27:12.207 回答
2

您的代码具有未定义的行为。如果未找到该元素,find将生成传入的第二个迭代器的副本,在这种情况下为v.end(). 取消引用end()迭代器是未定义的行为。

您必须测试迭代器,而不是值,以确定是否找到它:

if (i != v.end()) {
   std::cout << *i << "\n";
}
于 2013-04-09T18:27:16.123 回答
0

find函数不搜索范围的最后一个元素,因此您可以安全地将返回的迭代器与其进行比较,以了解搜索是否成功。

i = find(v.begin(), v.end(), 4);
//Unsuccessful find, so I want a value, say -1.
if (i != v.end())
   cout << *i << endl;
else
   cout << -1 << endl;

在您的示例中,确实最后一个元素恰好是不可取消引用的,但是如果是这种情况,您应该遵循相同的原则。例如,考虑您想要搜索集合的子序列的情况:您将首先选择定义范围的该集合的开始和结束条目,例如v.start()v.start()+2

auto e = v.start()+2;
i = find( v.start(), e, 4);
if (i != e) 
    cout << *i << endl; // will output 4 if found
else
    cout << -1 << endl;

这里e是有效的,但必须与它进行比较以确保返回的结果find在搜索范围内。

于 2013-04-09T18:30:46.547 回答