3

私はこのコードを持っています:

set<int>::iterator new_end = 
                   set_difference(set1.begin(), set1.end(),
                                  set2.begin(), set2.end(),
                                  set1.begin());
set1.erase(new_end, set1.end);

Visual Studioでコンパイルされ、正常に実行されます。ただし、前の質問で、人々はset'イテレータはであると想定されていると述べましたconst。規格にはそのようなものは見当たりません。誰かがそれがどこにあるのか、またはこれが明確に定義された動作であるかどうかを教えてもらえますか?

そうでない場合は、必要なことを実行するコードを提供してください。一時的なセットを作成せずにこれを行う方法はありますか?

4

5 に答える 5

7

あなたのコードは、のいくつかの不変条件に違反していset_differenceます。Josuttis Bookの420ページから:

  • 呼び出し元は、宛先範囲が十分に大きいこと、または挿入イテレーターが使用されていることを確認する必要があります。
  • 宛先範囲は、送信元範囲と重複してはなりません。

最初のセットを書き戻そうとしていますが、これは許可されていません。ソース範囲以外の場所に書き込む必要があります。そのために、3番目のセットを使用できます。

std::set<int> set3;
std::set_difference(set1.begin(), set1.end(),
                    set2.begin(), set2.end(),
                    std::inserter(set3, set3.begin()));

の2番目の引数std::inserterは、要素を挿入する場所のヒントです。これはヒントにすぎませんが、要素が適切な場所に配置されるので安心してください。 set3最初は空なので、begin()私たちが与えることができる唯一のヒントについてです。

の呼び出し後、set_difference元のコードに含まset3せようとしたものがset1含まれます。set3必要に応じて、またはswapそれを使用して続行できset1ます。

アップデート:

set1これのパフォーマンスについてはよくわかりませんが、に表示されるすべての要素を削除したい場合はset2、次のことを試してください。

for (std::set<int>::iterator i = set2.begin(); i != set2.end(); ++i)
{
    set1.erase(*i);
}
于 2009-05-26T20:45:42.953 に答える
5

それを解決するための1つの提案:

std::set<int> tmp;
std::set_difference(set1.begin(), set1.end(),
                    set2.begin(), set2.end(),
                    std::inserter(tmp, tmp.begin()));
std::swap(tmp, set1);

一時的なセットを使用せずにそれを行う方法を考えることはできません(コンテナーを反復処理し、個々の要素を消去することを除いて)。

于 2009-05-26T20:39:00.487 に答える
4

いいえ、ちがいます。SGISTLリファレンスから

  1. [first1、last1)と[result、result + n)は重複しません。
  2. [first2、last2)と[result、result + n)は重複しません。

また、Nikolai N Fetissovが指摘したように、begin()をOutputIteratorとして使用できるかどうかもわかりません。

于 2009-05-26T20:24:41.390 に答える
1

の5番目の引数set_differenceは、であると想定されています。ドキュメントOutputIteratorを参照してください。

于 2009-05-26T20:17:20.437 に答える
1

C ++標準では、setイテレータへの割り当てが許可されていないことを明示的に指定していませんが、set_differenceに対して、「結果の範囲は元の範囲のいずれとも重複してはならない」(25.3.5.3)と指定しています。

set1とset2の内容に恵まれたからといって、これまでのところうまくいったかもしれません。

于 2009-05-26T20:46:43.107 に答える