2

ベクトルのようなネストされていないコンテナから削除するときは、次のようなことをします。

struct is_to_remove
{
    is_to_remove(dynamic_bitset<>& x) : x(x) {}
    const bool operator()(unsigned int id)
    {
        return x[id];
    }

private:
    dynamic_bitset<> x;
};

inline static void remove_elements_in_vector(vector<unsigned int>& vec, boost::dynamic_bitset<>& to_remove)
{
    // use the erase-remove idiom to remove all elements marked in bitset
    vec.erase( remove_if(vec.begin(), vec.end(), is_to_remove(to_remove)), vec.end() );
}

それはいわゆるerase-removeイディオムです。

今、私は2番目のデータ構造vector<vector<unsigned int> >またはを持っています。ここで、ビットセットに従ってdeque<vector<unsigned int> >外部コンテナ要素(それ自体が内部タイプのコンテナです)を削除します。

  • このネストされたコンテナタイプでerase-removeイディオムを使用することは可能ですか?
  • もしそうなら、それはどのように可能ですか?
  • 制限はありますか?(例:vecのvecは可能ですが、vecのdequeはできません)?

私の最初の素朴なアプローチは次のとおりでした。remove_ifは、要素を順番に順番に繰り返し、次々に決定すると仮定しました。それは間違った仮定ですか?

struct is_to_remove_new
{
    is_to_remove_new(dynamic_bitset<>& x, unsigned int index) : x(x), index(index) {}
    const bool operator()(vector<unsigned int> & vec)
    {
        return x[index++];
    }

private:
    dynamic_bitset<> x;
    unsigned int index;
};

inline static void remove_elements_in_vectorvector(vector<vector<unsigned int> >& vec, boost::dynamic_bitset<>& to_remove)
{
    // use the erase-remove idiom to remove all elements marked in bitset
    vec.erase( remove_if(vec.begin(), vec.end(), is_to_remove_new(to_remove, 0)), vec.end() );
}

結果は間違っているので、ここで正しい解決策を探しています。私はいくつかのことを想定したと思いますが、それは保証されていません。私にとって、基本的な質問は次のとおりです。削除するかどうかを確認するために内部コンテナのIDを取得する方法。
上に投稿された私の素朴なアプローチは、順次処理を数え、想定しています。

ご協力いただきありがとうございます。

サシャ

更新と警告

ベクトルoベクトルの場合、Stasソリューションはうまく機能しています。ただし、両端キューは連続して保存されないため、このソリューションはベクトルの両端キューでは機能しないと思います。これは、ファンクターのインデックスの計算が失敗することを意味します。

誰かがそれを確認できますか?

4

1 に答える 1

3

ベクトルにどの要素が含まれているかは関係ありません。それらのどれを削除するかを定義すると、それらは削除されます。

あなたが言ったように、問題はベクトル内の要素をどのように識別するかです。最も明白な答えは、そのインデックスによるもの[0; vector_size - 1]です。

ベクトルのおかげで、要素自体によって要素インデックスを簡単に取得できます。

std::vector<std::string> vec;
vec.push_back("zero");
vec.push_back("one");
vec.push_back("two");

std::string& elem = vec[2];
int index = std::distance(&vec[0], &elem); // get element index by element itself
// index == 2

remove_ifしたがって、アルゴリズム述語内のインデックスによってベクトル要素を簡単に識別できます。次の例を見てください。これはかなりばかげており、ハードコードされstd::bitset<6>ていますが、これは単なる例です。

#include <vector>
#include <string>
#include <bitset>

struct ToRemove
{
   ToRemove(std::vector<std::string>& vec, const std::string& mask) 
   : m_vec(vec)
   , m_mask(mask) 
   {}

   bool operator()(std::string& obj)
   {
      const int index = std::distance(&m_vec[0], &obj);
      return m_mask[index];
   }

   std::vector<std::string>& m_vec;
   std::bitset<6> m_mask;
};

使用法

int main (int argc, char const *argv[])
{
   std::vector<std::string> vec;
   vec.push_back("zero");
   vec.push_back("one");
   vec.push_back("two");
   vec.push_back("three");
   vec.push_back("four");
   vec.push_back("five");

   std::string mask = ("010011"); // Remove "zero", "one" and "four"
   vec.erase(remove_if(vec.begin(), vec.end(), ToRemove(vec, mask)), vec.end());

   for (unsigned i = 0; i < vec.size(); ++i)
   {
      std::cout << vec[i] << " ";
   }
   std::cout << std::endl;

   return 0;
}

結果

 two three five 
于 2010-12-07T22:19:21.840 に答える