我需要在C++中解析成千上万的简单条目。我只用过C语言编程,所以我可能会错过一些更高的函数来简化这项任务。
一个条目由4个单独的值组成:sender
、receiver
、date
和type of mail
。其中三个值是string
,最后一个值是一个integer
。我的目标(在处理完所有条目后(是打印出输入中收到的所有不同条目,以及每个条目收到的次数。
这意味着,如果在输入中多次出现相同的发件人、收件人、日期和邮件类型,则输出将显示该条目已收到,例如5次。
最好的方法是什么?我尝试了C++map
,但无法使其工作。
我建议用operator<
定义一个类,这样就可以将该类的实例存储在std::map
中。std::map
可用于从对象映射,比较等于和的计数。如果lhs < rhs
和rhs < lhs
都不为真,则对象被认为是相等的,因此只需要operator<
过载。
您还可以添加operator>>
和operator<<
重载,从而可以从流中读取和写入对象。
它可能看起来像这样:
#include <iostream>
#include <map>
#include <string>
#include <tuple>
struct foo {
std::string sender;
std::string receiver;
std::string date;
int type_of_mail;
// compare two foo instances:
bool operator<(const foo& rhs) const {
return std::tie(sender, receiver, date, type_of_mail) <
std::tie(rhs.sender, rhs.receiver, rhs.date, rhs.type_of_mail);
}
// read a foo from an istream:
friend std::istream& operator>>(std::istream& is, foo& f) {
return is >> f.sender >> f.receiver >> f.date >> f.type_of_mail;
}
// write a foo to an ostream:
friend std::ostream& operator<<(std::ostream& os, const foo& f) {
return os << f.sender << ' ' << f.receiver << ' ' << f.date << ' '
<< f.type_of_mail;
}
};
int main() {
std::map<foo, unsigned> counts;
foo tmp;
// read foos from any istream
while(std::cin >> tmp) {
++counts[tmp]; // count
}
// print the count for each
for(const auto&[f, count] : counts) {
std::cout << count << ' ' << f << 'n';
}
}
演示
您可以使用实现比较的结构将其存储在集合/多集合中:
struct Entry {
friend bool operator<(const Entry& lhs, const Entry& rhs) {
if (lhs.sender < rhs.sender) return true;
if (lhs.sender > rhs.sender) return false;
if (lhs.receiver < rhs.receiver) return true;
if (lhs.receiver > rhs.receiver) return false;
if (lhs.date < rhs.date) return true;
if (lhs.date > rhs.date) return false;
if (lhs.type_of_mail < rhs.type_of_mail) return true;
return false;
}
std::string sender;
std::string receiver;
std::string date; // this should be a proper date time, otherwise DST & timezones might be a problem
int type_of_mail; // this should be enum
};
int main() {
std::set<Entry> entries;
// or
std::multiset<Entry> entries_duplications_allowed;
// you might insert elements here
// you might loop over entries using e.g. range for here
}
我建议为要搜索的每个字段提供一个数据表和一个索引表。(实际上,这闻起来像是你应该使用数据库,而不是编写数据库(
将您的所有记录放入std::vector<Record>
中
为每个关键字段创建一个std::map<key_text, vector_index>
。
查找记录:
- 使用关键字(字符串(搜索相应的
map
(索引表( - 如果找到,请提取索引字段
- 使用
std::vector<Record>
的索引文件
多字段关键字搜索更困难,可能会占用更多空间(如果使用索引数据结构(。
IMHO,你最好的方法是使用数据库。