2

私は無視しなければならない配列を持っていますrepetitive.

例えば1 2 4 3 3 0 1 2 0

私がしたことは、数字をチェックして次のようなことを試したことです\0NULL、どちらも値が0であるため、解決策ではありません。では、インデックスを空にしたり、単に無視したりする方法はありますか? 数字はランダムでなければならないので、次のような宣言はできません

array[i]=123;
if(array[i]==123) dont_print_out();
4

2 に答える 2

5

配列が単純な C++ 配列である場合、アイテムを「削除」する方法はありません。唯一の解決策は、残りのアイテムを左にシフトすることです。

配列が の場合std::vector、関数を使用できますerase。ただし、ベクター内の基礎となるデータの構造により、基本的に以前と同じことを行います。これは非効率的です。

シーケンス内でランダムに配置されたアイテムを効率的に削除したい場合は、std::list.

最後に、目的を達成するために、std::setまたはを見てくださいstd::unordered_set。これらのコンテナは、アイテムが一意であることを保証します。

于 2013-06-12T14:43:30.620 に答える
2
  1. 配列の代わりに を使用するstd::vectorと、項目を消去できます1
  2. 元の順序を維持する必要がない場合は、並べ替えを行うのがおそらく最も簡単でstd::unique、重複を排除するために使用します。

コードは次のようになります。

std::vector<int> numbers;

srand(time(NULL));

std::generate_n(std::back_inserter(numbers), 10, rand);
std::sort(numbers.begin(), numbers.end());
std::copy(numbers.begin(), std::unique(numbers.begin(), numbers.end()), 
          std::ostream_iterator<int>(std::cout, "\t"));

 // Or, as @Chris pointed out:
 std::unique_copy(numbers.begin(), numbers.end(),
          std::ostream_iterator<int>(std::cout, "\t"));

std::unique一意の数値の範囲の最後に反復子を返すので、実際には他のものをまったく消去する必要がないことに注意してください。表示する範囲の最後としてそれを使用するだけです。

また、ここで数値を生成したので、何かを削除することは実際にはかなり珍しいことです. の典型的な実装によって生成される数値の範囲を考えるとrand()、わずか10回の反復で重複が生成されるのを見るのはかなり珍しいことです. .

元の順序を維持する必要がある場合は、いくつかの選択肢があります。1 つは、印刷時に各アイテムをstd::set(またはstd::unordered_set) に挿入し、セットへの挿入が成功した (つまり、以前は存在しなかった) だけを印刷することです。


1. ただし、これは配列 よりも優先される多くの理由の 1 つにすぎません。std::vector

于 2013-06-12T14:52:38.953 に答える