C++ 根据不同的标准C+维护一组独特的元素+;STL

C++ 根据不同的标准C+维护一组独特的元素+;STL,c++,C++,我必须开发一个组件 将有一个超过 一个类的100000个实例。而我 是否要基于生成报告 不同标准(成员) 属于特定类别的。例如 数据字段id为的employee类, 姓名、地址、电话号码。报告 发电将基于 名字升序 名字从下到下 地址升序 菲诺上升 唯一名称 唯一地址 唯一电话号码 每次调用的实例的运行时迭代非常慢,因为它是对大量实例的线性操作,需要排序机制 因此,我以不同的排序方式将每个实例的指针存储在一个容器中。但是需要比需要更多的内存。请给我一个更好的方法。我已经发布了我在上面实现的示例

我必须开发一个组件 将有一个超过 一个类的100000个实例。而我 是否要基于生成报告 不同标准(成员) 属于特定类别的。例如 数据字段id为的employee类, 姓名、地址、电话号码。报告 发电将基于


  • 名字升序
  • 名字从下到下
  • 地址升序
  • 菲诺上升
  • 唯一名称
  • 唯一地址
  • 唯一电话号码
  • 每次调用的实例的运行时迭代非常慢,因为它是对大量实例的线性操作,需要排序机制

    因此,我以不同的排序方式将每个实例的指针存储在一个容器中。但是需要比需要更多的内存。请给我一个更好的方法。我已经发布了我在上面实现的示例代码片段

    class Employee
    {
        int    m_id;
        string m_name;
        string m_addr;
        string m_phone;
    
    public:
        Employee(int id, string name, string addr, string phone) : 
             m_id(id), m_name(name), m_addr(addr), m_phone(phone) { }
    
        int    id()      const { return m_id;    }
        string name()    const { return m_name;  }
        string addr()    const { return m_addr;  }
        string phoneno() const { return m_phone; }
    };
    
    //custom predicate for std containers
    struct IDComparator
    {
        bool operator() (const Employee* e1, const Employee* e2 )
        {
           return e1->id() < e2->id();
        }
    };
    
    struct NameComparator
    {
        bool operator() (const Employee* e1, const Employee* e2 )
        {
           return e1->name() < e2->name();
        }
    }
    
    struct AddressComparator
    {
        bool operator() (const Employee* e1, const Employee* e2 )
        {
           return e1->addr() <  e2->addr();
        }
    };
    
    struct PhoneComparator
    {
        bool operator() (const Employee* e1, const Employee* e2 )
        {
           return e1->phoneno() < e2->phoneno();
        }
    };
    
    
    //Class which holds huge number of employee instances
    class Dept
    {
    private:
        typedef set<Employee*, IDComparator> EMPID; //unnique id
        typedef EMPID::iterator EMPID_ITER;
    
        typedef multiset<const Employee*, NameComparator> EMPNAME;   // for sorted names
        typedef EMPNAME::iterator NAME_ITER;
    
        typedef multiset<const Employee*, AddressComparator> EMPADDR; // for sorted addr
        typedef EMPADDR::iterator ADDR_ITER;
    
        typedef multiset<const Employee*, PhoneComparator> EMPPHONE;  // for sorted phoneno
        typedef EMPPHONE::iterator PHONE_ITER;
    
    private:
        EMPID    m_empids;
        EMPNAME  m_names ;
        EMPADDR  m_addr;
        EMPPHONE m_phoneno;
    
    public:
        Dept() { }
        ~Dept() { //delete the instances of employees }
    
        void add(Employee* e) 
        {
            EMP_ITER iter = m_empids.insert(e).first;
            const Employee* empptr = &*iter;
            m_names.insert(empptr);    // adds employee pointer to name multimap
            m_addr.insert(empptr);     // adds employee pointer to addr multimap
            m_phoneno.insert(empptr);  // adds employee pointer to phone multimap
        }
    
    
        void print_emp_dtls()       const; //prints all the emp dtls iterating though EMPID 
    
        void print_unique_names()   const; //iterate EMPNAME & use upperbound & lowerbound, prints unique names 
        void print_asc_name()       const; //iterate EMPNAME & prints all names in ascending order
        void print_desc_name()      const; //back iterate EMPNAME & prints all names in descending order
    
        void print_unique_adrr()    const; //iterate EMPADDR & use upperbound & lowerbound, prints unique address
        void print_asc_addr()       const; //iterate EMPADDR & prints all addr in ascending order
        void print_desc_addr()      const; //back iterate EMPADDR & prints all address in descending order
    
        void print_unique_phoneno() const; //iterate EMPPHONE & use upperbound & lowerbound,prints unique phoneno
        void print_asc_phoneno()    const; //iterate EMPPHONE & prints all phoneno in ascending order
        void print_desc_phoneno()   const; //back iterate EMPPHONE & prints all phoneno in     };
    
    class员工
    {
    国际货币基金组织;
    字符串m_name;
    字符串m_addr;
    串手机;
    公众:
    员工(输入id、字符串名称、字符串地址、字符串电话):
    m_id(id),m_name(name),m_addr(addr),m_phone(phone){}
    int id()常量{return m_id;}
    string name()常量{return m_name;}
    字符串addr()常量{return m_addr;}
    字符串phoneno()常量{return m_phone;}
    };
    //std容器的自定义谓词
    结构IDComparator
    {
    布尔运算符()(常数雇员*e1,常数雇员*e2)
    {
    返回e1->id()id();
    }
    };
    结构名称比较器
    {
    布尔运算符()(常数雇员*e1,常数雇员*e2)
    {
    返回e1->name()name();
    }
    }
    结构地址比较器
    {
    布尔运算符()(常数雇员*e1,常数雇员*e2)
    {
    返回e1->addr()addr();
    }
    };
    结构音素比较器
    {
    布尔运算符()(常数雇员*e1,常数雇员*e2)
    {
    返回e1->phoneno()phoneno();
    }
    };
    //类,该类包含大量employee实例
    班级部
    {
    私人:
    typedef set EMPID;//unnique id
    typedef EMPID::迭代器EMPID_ITER;
    typedef multiset EMPNAME;//用于排序名称
    typedef EMPNAME::迭代器名称\u ITER;
    typedef multiset EMPADDR;//用于已排序的地址
    typedef EMPADDR::迭代器地址;
    typedef multiset emphone;//用于已排序的电话否
    typedef emphone::迭代器电话;
    私人:
    EMPID m_empids;
    EMPNAME m_名称;
    EMPADDR mu addr;
    Emphone m_phoneno;
    公众:
    Dept(){}
    ~Dept(){//删除员工的实例}
    无效添加(员工*e)
    {
    EMP_ITER ITER=m_empids.insert(e).first;
    施工人员*empptr=&*iter;
    m_names.insert(emptr);//将员工指针添加到名称多重映射
    m_addr.insert(emptr);//将雇员指针添加到addr multimap
    m_phoneno.insert(emptr);//将员工指针添加到电话多重映射
    }
    void print\u emp\u dtls()const;//打印通过EMPID迭代的所有emp DTL
    void print_unique_names()const;//迭代EMPNAME并使用上限和下限,打印唯一名称
    void print\u asc\u name()const;//迭代EMPNAME&按升序打印所有名称
    void print_desc_name()const;//反向迭代EMPNAME&按降序打印所有名称
    void print_unique_adrr()const;//迭代EMPADDR&使用上限和下限,打印唯一地址
    void print\u asc\u addr()const;//迭代EMPADDR&按升序打印所有addr
    void print_desc_addr()const;//反向迭代EMPADDR&按降序打印所有地址
    void print_unique_phoneno()const;//迭代emphone并使用上限和下限,打印唯一的phoneno
    void print\u asc\u phoneno()const;//迭代emphone&按升序打印所有phoneno
    void print_desc_phoneno()const;//反向迭代emphone&在}中打印所有phoneno;
    
    看看
    boost::multi_index
    。有一个容器
    boost::multi_index_contaier
    ,允许您使用各种键搜索项目。

    似乎是以下方面的完美候选:

    Boost多索引容器 库提供了一个类模板 命名的多索引容器 启用容器的构造 使用维护一个或多个索引 不同的排序和访问 语义


    我过去成功地使用了Boost.Multi_索引。乍一看,您可能会觉得它很奇怪,但实际上它是一个有趣的库。在使用它时请记住,在定制的容器中提供的不是“如何”,而是“什么”。假设您具有以下类型:

    struct user_t
    {
        string id, name, email;
        int age;
        friend ostream& operator<<(ostream& output_stream, const user_t& user)
        {
            return output_stream
                << user.id    << " "
                << user.name  << " "
                << user.age   << " "
                << user.email << "\n";
        }
        friend istream& operator>>(istream& input_stream, user_t& user)
        {
            return input_stream >> user.id >> user.name >> user.age >> user.email;
        }
    };
    
    然后,我们用所需的索引定义“数据库”:

    typedef multi_index_container<
        user_t,
        indexed_by
        <
          ordered_unique<tag<by_id>, member<user_t, string, &user_t::id> >,
          ordered_non_unique<tag<by_name>, member<user_t, string, &user_t::name> >,
          ordered_non_unique<tag<by_age>, member<user_t, int, &user_t::age> >,
          ordered_non_unique<tag<by_email>, member<user_t, string, &user_t::email> >
        >
    > user_db;
    

    谢谢各位。。。。我对STL很熟悉,但对提升库来说是新手。这对我有用。@Naveen:那么你应该接受正确的答案:这就是你在堆栈溢出时说“谢谢你的解决方案”的方式!
    typedef multi_index_container<
        user_t,
        indexed_by
        <
          ordered_unique<tag<by_id>, member<user_t, string, &user_t::id> >,
          ordered_non_unique<tag<by_name>, member<user_t, string, &user_t::name> >,
          ordered_non_unique<tag<by_age>, member<user_t, int, &user_t::age> >,
          ordered_non_unique<tag<by_email>, member<user_t, string, &user_t::email> >
        >
    > user_db;
    
    indexed_by
    <
      ordered_unique<tag<by_id>, member<user_t, string, &user_t::id> >,
      ordered_non_unique<tag<by_name>, member<user_t, string, &user_t::name> >,
      ordered_non_unique<tag<by_age>, member<user_t, int, &user_t::age> >,
      ordered_non_unique<tag<by_email>, member<user_t, string, &user_t::email> >
    >
    
     user_db load_information()
    {
        ifstream info_file("information.txt");
        user_db db;
        user_t user;
        while(info_file >> user)
            db.insert(user);
        return db;
    }
    template <typename index_t>
    void save_information_by(ostream& output_stream, const index_t& index)
    {
        ostream_iterator<user_t> serializer(output_stream);
        copy(index.begin(), index.end(), serializer);
    }
    int main()
    {
        ofstream
            by_id_file("by_id.txt"),
            by_name_file("by_name.txt"),
            by_age_file("by_age.txt"),
            by_email_file("by_email.txt");
        user_db db = load_information();
        // You see why we created the tags,
        // if we didn't we had to specify the index like the following:
        // const auto& name_index  = db.get<by_name>(); ==
        // const auto& name_index  = db.get<1>();
        const auto& id_index    = db.get<by_id>();
        const auto& name_index  = db.get<by_name>();
        const auto& age_index   = db.get<by_age>();
        const auto& email_index = db.get<by_email>();
        save_information_by(by_id_file, id_index);
        save_information_by(by_name_file, name_index);
        save_information_by(by_age_file, age_index);
        save_information_by(by_email_file, email_index);
    }