C++ 根据不同的标准C+维护一组独特的元素+;STL
我必须开发一个组件 将有一个超过 一个类的100000个实例。而我 是否要基于生成报告 不同标准(成员) 属于特定类别的。例如 数据字段id为的employee类, 姓名、地址、电话号码。报告 发电将基于C++ 根据不同的标准C+维护一组独特的元素+;STL,c++,C++,我必须开发一个组件 将有一个超过 一个类的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);
}