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 を出力するという事実は無関係です。

失敗しても 2 番目の引数のコピーを返すため、あいまいな状況にはなりません。この場合、 を返しますv.end()std::findが成功したかどうかを確認する必要があります。

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

あなたのコードには未定義の動作があります。要素が見つからない場合、find渡された 2 番目の反復子 (この場合は ) のコピーが生成されます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 に答える