4

オブジェクトのメンバーフィールドの値に基づいてコンテナからオブジェクトを削除する効率的な方法があるかどうかを知りたいです。たとえば、文字列のリストを指定してstl :: uniqueを使用すると、次のことができます。

#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;

bool stringCompare(const string & l, const string & r)                                                                                   
{                                                                                                                                    
   return (l==r);                                                                                                                         
}

int main()                                                                                                                               
{                                                                                                                                        

  list<string> myStrings;                                                                                                                
  myStrings.push_back("1001");                                                                                                           
  myStrings.push_back("1001");                                                                                                           
  myStrings.push_back("81");                                                                                                             
  myStrings.push_back("1001");                                                                                                           
  myStrings.push_back("81");                                                                                                             

  myStrings.sort();                                                                                                                      
  myStrings.erase(unique(myStrings.begin(), myStrings.end(), stringCompare), myStrings.end());                                           

  list<string>::iterator it;                                                                                                             
  for(it = myStrings.begin(); it != myStrings.end(); ++it)                                                                               
  {                                                                                                                                      
    cout << *it << endl;                                                                                                                 
  }                                                                                                                                      

  return     0;                                                                                                                              
}

プリント1001、81 .. ..

次のコードで同様のことを行う方法はありますか、それとも演算子を使用してコンテナーを反復処理することで「手動で」比較を実行する必要がありますか。これ以上洗練されたソリューションは考えられませんでした。多くのコードを記述せずにこれが可能かどうかを知りたいと思います。どんな助けでも大歓迎です!

class Packet
{
public:
Packet(string fTime, string rID) : filingTime(fTime), recordID(rID)

  string getFilingTime() {return filingTime;}
  string getRecordId() {return recordID;}

private:
  string filingTime;
  string recordID;

};

int main()
{
vector<Packet*> pkts;
pkts.push_back(new Packet("10:20", "1004"));
pkts.push_back(new Packet("10:20", "1004")); // not unique (duplicate of the line above)
pkts.push_back(new Packet("10:20", "251"));
pkts.push_back(new Packet("10:20", "1006"));

// remove packet from vector if time and ID are the same

return 0;
}

ありがとう

4

2 に答える 2

9

使用できる2つのオプションstd::unique

  1. operator==のメソッドを定義し、Packetに変更vector<Packet*>vector<Packet>ます。

    bool Packet::operator==(const Packet& rhs) const
    {
        if (getFilingTime() != rhs.getFilingTime())
            return false;
        if (getSpid() != rhs.getSpid())
            return false;
        return true;
    }
    
    //etc.
    
    int main()
    {
        vector<Packet> pkts;
        pkts.push_back(Packet("10:20", "1004"));
        pkts.push_back(Packet("10:20", "1004")); // not unique (duplicate of the line above)
        pkts.push_back(Packet("10:20", "251"));
        pkts.push_back(Packet("10:20", "1006"));
    
        // remove packet from vector if time and ID are the same
    
         pkts.erase(unique(pkts.begin(), pkts.end()), pkts.end());                   
    
        return 0;
    }
    
  2. ベクトルをとして保持しvector<Packet*>、要素を比較するメソッドを定義します。

    bool comparePacketPtrs(Packet* lhs, Packet* rhs)
    {
        if (lhs->getFilingTime() != rhs->getFilingTime())
            return false;
        if (lhs->getSpid() != rhs->getSpid())
            return false;
        return true;
    }
    
    //etc.
    
    int main()
    {
        vector<Packet*> pkts;
        pkts.push_back(new Packet("10:20", "1004"));
        pkts.push_back(new Packet("10:20", "1004")); // not unique (duplicate of the line above)
        pkts.push_back(new Packet("10:20", "251"));
        pkts.push_back(new Packet("10:20", "1006"));
    
        // remove packet from vector if time and ID are the same
    
         pkts.erase(unique(pkts.begin(), pkts.end(), comparePacketPtrs), pkts.end());                   
    
        return 0;
    }
    
于 2012-10-11T23:41:31.073 に答える
6

の代わりに、要素を(またはC ++ 11で)にunique挿入するだけで済みます。setunordered_set

どちらの方法を選択する場合でも、の比較演算子を定義する必要がありますPacket。の場合unique、必要になりますoperator==; setあなたが必要になるからですoperator<。完全を期すために、両方とそれに対応するものを定義する必要があります。

class Packet {
    …
    bool operator==(const Packet& p) const {
        return fillingTime == p.fillingTime && recordID == p.recordID;
    }
    bool operator<(const Packet& p) const {
        return fillingTime < p.fillingTime ||
               (fillingTime == p.fillingTime && recordID < p.recordID);
    }
    bool operator!=(const Packet& p) const { return !(*this == p); }
    bool operator> (const Packet& p) const { return p < *this; }
    bool operator>=(const Packet& p) const { return !(*this < p); }
    bool operator<=(const Packet& p) const { return !(p < *this); }
    …
};

C ++ 11を使用する場合unordered_setは、さらに一歩進んでハッシュ関数を定義する必要があります。

編集:私はあなたがへのポインタを保存していることに気づきましたPacket。なんで?Packet直接保管するだけです。

于 2012-10-11T23:40:18.613 に答える