用C++中的多值键查找项目的最快方法是什么



我需要在C++中解析成千上万的简单条目。我只用过C语言编程,所以我可能会错过一些更高的函数来简化这项任务。

一个条目由4个单独的值组成:senderreceiverdatetype of mail。其中三个值是string,最后一个值是一个integer。我的目标(在处理完所有条目后(是打印出输入中收到的所有不同条目,以及每个条目收到的次数。

这意味着,如果在输入中多次出现相同的发件人、收件人、日期和邮件类型,则输出将显示该条目已收到,例如5次。

最好的方法是什么?我尝试了C++map,但无法使其工作。

我建议用operator<定义一个类,这样就可以将该类的实例存储在std::map中。std::map可用于从对象映射,比较等于的计数。如果lhs < rhsrhs < 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>

查找记录:

  1. 使用关键字(字符串(搜索相应的map(索引表(
  2. 如果找到,请提取索引字段
  3. 使用std::vector<Record>的索引文件

多字段关键字搜索更困难,可能会占用更多空间(如果使用索引数据结构(。

IMHO,你最好的方法是使用数据库。

最新更新