3

uniqueC ++標準ライブラリアルゴリズム(を使用)を使用しようとしていますBinaryPredicate

ペアのベクトルを作成しました。各ペアは「(first = 4つのdoubleのベクトル、second =整数)」のようなものです。2番目の要素はインデックスとして機能するため、 `uniqueを使用した後でも、元のインデックスを確認できます。

以下の例では、次のようなものを作成しました。


10 20 30 40, 1
10 20 30 40, 2
10 20 30 40, 3
10 20 30 40, 4
10 20 30 40, 5
10 20 30 40, 6

次に、一意の関数を使用して、各ペアの最初の要素のみを比較します。カスタマイズバイナリ予測子を使用しましたuniquepred。確かに、それは機能しますが、ベクトルは使用後に縮小されませんunique

期待される結果

Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=1

実結果

Size before=6
equal!
equal!
equal!
equal!
equal!
Size after=6

最小限の作業例を次に示します。これをデバッグするのを手伝ってください。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef std::vector<double> V1db;
typedef std::pair<V1db, int > Pairs;
typedef std::vector<Pairs> Vpairs;

bool uniquepred( const Pairs& l, const Pairs& r) {
    if (l.first==r.first)
        cout<<"equal!"<<endl;
    return l.first == r.first;
}
int main()
{
    Vpairs ak;
    V1db u2(4);
    u2[0]=10;u2[1]=20;u2[2]=30;u2[3]=40;
    Pairs m2;
    m2.first = u2;
    m2.second= 1;
    ak.push_back(m2);
    m2.second= 2;
    ak.push_back(m2);
    m2.second= 3;
    ak.push_back(m2);
    m2.second= 4;
    ak.push_back(m2);
    m2.second= 5;
    ak.push_back(m2);
    m2.second= 6;
    ak.push_back(m2);
    cout<<"Size before="<<ak.size()<<endl;
    unique(ak.begin(), ak.end(), uniquepred);
    cout<<"Size after="<<ak.size()<<endl;

    return 0;
}
4

2 に答える 2

9

あなたがしたい:

ak.erase(unique(ak.begin(), ak.end(), uniquepred), ak.end());

これはstd::unique、値を並べ替えるためです。ただし、それらは削除されず、から戻るbegin()イテレータまでの新しい範囲が残りuniqueます。この並べ替え以外は、コンテナ自体は変更されません。

イテレータが無効になる場合でも、ベクトルには「位置Xで削除」メソッドはありません。設計によるuniqueアルゴリズムは、基礎となるコンテナについて何も知らないため、有効なイテレータのペアで機能します。唯一の要件は、それらがであるということですForwardIterators

于 2011-09-21T17:32:00.463 に答える
6

std::unique 動作します。お気に入りのC++ライブラリのドキュメントでそれを調べて、それが何をするのかを調べるのを忘れていました。

std::removeそれは、実際には単に物を動かし、新しい範囲へのエンドイテレータを提供するという点で、少し奇妙に機能します。基になるコンテナのサイズは変更されません。自分で消去する必要があります。

ak.erase(std::unique(ak.begin(), ak.end(), uniquepred), ak.end());
于 2011-09-21T17:34:33.123 に答える