2

があり、std::set同様の隣接する要素を消去する必要があります:

DnaSet::const_iterator next = dna_list.begin();
DnaSet::const_iterator actual = next;
++next;

while(next != dna_list.end()) // cycle over pairs, dna_list is the set
{
    if (similar(*actual, *next))
    {
        Dna dna_temp(*actual);  // copy constructor
        dna_list.erase(actual); // erase the old one
        do
        {
           dna_temp.mutate(); // change dna_temp
        } while(!dna_list.insert(dna_temp).second);  // insert dna_temp
    }
    ++actual;
    ++next;
}

プログラムがメインループから抜け出せないことがあります。の最後の要素を消去すると問題が発生すると思いますdna_list。このタスクを実行する正しい方法は何ですか?

4

2 に答える 2

5

actual = nextではなく使用し++actualます。

を消去するactualと、それは無効なイテレータであるため、++actual奇妙な動作をします。nextそのままにしておく必要があるため、に割り当てると機能actualするnextはずです。

于 2010-07-28T23:26:52.473 に答える
2

最良のオプションは、similar()述語を使用する比較ファンクターを作成することです。次に、その比較ファンクターを使用してセットを作成するだけで、完了です。セット自体は、2つの類似した要素を同一と見なし、最初の要素のみをに入れます。

struct lt_different {
    bool operator()(int a, int b) {
        return a < b && !similar(a, b);
    }

private:
    bool similar(int a, int b)
    {
        // TODO:when are two elements similar?
        const int EPSILON = 2;
        return abs(a - b) < EPSILON;
    }
};

// ...
set<int> o;  // fill this set with your data

// copy your data to a new set that rejects similar elements
set<int,lt_different> s(o.begin(), o.end(), lt_different());

setを操作できますs:要素の挿入、要素の削除、要素の変更-そしてセット自体は、2つの類似した要素がセットに存在しないことを確認します。

とは言うものの、別の選択肢がある場合に限り、自分でアルゴリズムを作成することもできます。std::adjacent_find()から見てみましょう<algorithm>。2つの連続した同一要素の最初の出現を検出します。その位置を保持します。それが見つかったら、これらの要素とは異なる、そのポイントからの最初の要素を見つけます。最終的に、連続する類似した要素の範囲を示す2つのイテレータが作成されます。セットのerase()メソッドを使用してそれらを削除できます。これは、2つのイテレーターを必要とするオーバーロードがあるためです。

泡立て、すすぎ、セット全体で繰り返します。

于 2010-07-28T23:28:08.413 に答える