如何(有效地)插入以地图为值的地图?
How to (efficiently) insert into a map with a map as value?
我正在编写一个 C++ 程序,逐行读取一个大文件,并将每一行信息(经过一些处理后)插入 unordered_map。
这是 unordered_map 的声明:
unordered_map<int, unordered_map<int, int> > entries;
我要插入的是(这是在我处理文本文件每一行的循环代码块中):
unordered_map<int, int> tmp;
tmp[y] = z;
entries[x] = tmp;
但这被证明在性能方面表现不佳。
我试过创建一个 pair<int, pair<int, int>>
并使用 entries.insert(the_pair)
插入它,但我无法编译它(得到:no matching member function for call to 'insert'
)。
编辑:
程序看起来像这样的:
ifstream ifile(path-to-file);
string line;
unordered_map<int, unordered_map<int, int> > entries;
while (getline(ifile, line)) {
// some processing with line to find (int) x and (int) y
if (entries.find(x) == entries.end()) {
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
auto &tmp_m = iter_and_success.first->second;
tmp_m[y] = 1;
}
else {
unordered_map<int, int> r = entries[x];
if (r.count(y) == 0)
entries[x][y] = (int) r.size() + 1;
}
}
我认为你最好的选择就是将 child unordered_map
移动到 parent 一个:
entries[x] = std::move(tmp);
这样您将避免 tmp
.
的额外副本
另一种方法是在插入 child 地图后 填充它 。
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
auto& tmp = iter_and_success.first->second;
tmp[y] = z;
实际上,如果 x
发生多次,您会将数据附加到 child 映射(如果这是不需要的行为 - 只需检查 bool 标志并采取相应措施)。
ifstream ifile(path-to-file);
string line;
unordered_map<int, unordered_map<int, int> > entries;
while (getline(ifile, line)) {
// some processing with line to find (int) x and (int) y
// This will insert a new map only if x wasn't present
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
// This will be 1 if a new map was inserted
auto value_to_insert = static_cast<int>(iter_and_success.first->second.size()) + 1;
// This will do anything only if y wasn't present in sub-map
iter_and_success.first->second.emplace(y, value_to_insert);
}
我正在编写一个 C++ 程序,逐行读取一个大文件,并将每一行信息(经过一些处理后)插入 unordered_map。
这是 unordered_map 的声明:
unordered_map<int, unordered_map<int, int> > entries;
我要插入的是(这是在我处理文本文件每一行的循环代码块中):
unordered_map<int, int> tmp;
tmp[y] = z;
entries[x] = tmp;
但这被证明在性能方面表现不佳。
我试过创建一个 pair<int, pair<int, int>>
并使用 entries.insert(the_pair)
插入它,但我无法编译它(得到:no matching member function for call to 'insert'
)。
编辑:
程序看起来像这样的:
ifstream ifile(path-to-file);
string line;
unordered_map<int, unordered_map<int, int> > entries;
while (getline(ifile, line)) {
// some processing with line to find (int) x and (int) y
if (entries.find(x) == entries.end()) {
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
auto &tmp_m = iter_and_success.first->second;
tmp_m[y] = 1;
}
else {
unordered_map<int, int> r = entries[x];
if (r.count(y) == 0)
entries[x][y] = (int) r.size() + 1;
}
}
我认为你最好的选择就是将 child unordered_map
移动到 parent 一个:
entries[x] = std::move(tmp);
这样您将避免 tmp
.
另一种方法是在插入 child 地图后 填充它 。
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
auto& tmp = iter_and_success.first->second;
tmp[y] = z;
实际上,如果 x
发生多次,您会将数据附加到 child 映射(如果这是不需要的行为 - 只需检查 bool 标志并采取相应措施)。
ifstream ifile(path-to-file);
string line;
unordered_map<int, unordered_map<int, int> > entries;
while (getline(ifile, line)) {
// some processing with line to find (int) x and (int) y
// This will insert a new map only if x wasn't present
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
// This will be 1 if a new map was inserted
auto value_to_insert = static_cast<int>(iter_and_success.first->second.size()) + 1;
// This will do anything only if y wasn't present in sub-map
iter_and_success.first->second.emplace(y, value_to_insert);
}