Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过关键点向量从地图中获取地图_C++_C++17_Stdmap - Fatal编程技术网

C++ 通过关键点向量从地图中获取地图

C++ 通过关键点向量从地图中获取地图,c++,c++17,stdmap,C++,C++17,Stdmap,我想知道,是否有std::map函数来接收由键的std::vector定义的子映射。因此,就像std::map.at(key)函数一样,它有一个std::vector键。我知道我可以迭代映射并将映射对添加到新映射,但我想知道,是否有内置函数,或者是否有更快的方法来获取子映射 示例代码: std::map<std::string, int> map = {{"a", 1}, {"b", 2}, {"c", 3}, {"d", 4}, {"e", 5}}; std::vector<

我想知道,是否有std::map函数来接收由键的std::vector定义的子映射。因此,就像
std::map.at(key)
函数一样,它有一个std::vector键。我知道我可以迭代映射并将映射对添加到新映射,但我想知道,是否有内置函数,或者是否有更快的方法来获取子映射

示例代码:

std::map<std::string, int> map = {{"a", 1}, {"b", 2}, {"c", 3}, {"d", 4}, {"e", 5}};
std::vector<std::string> keys = {"a", "c", "d"};
// using iteration:
std::map<std::string, int> new_map;
for(auto it = map.begin(); it != map.end(); ++it){
    if(std::find(keys.begin(), keys.end(), it->first) != keys.end()){
        new_map.insert(*it);
    }
}
// new_map should be {{"a",1}, {"c",3}, {"d",4}}

// What I am hoping to find is something like:
new_map = map.at(keys);

//resulting in the same new_map {{"a",1}, {"c",3}, {"d",4}}.
std::map map={{“a”,1},{“b”,2},{“c”,3},{“d”,4},{“e”,5};
向量键={a”,“c”,“d”};
//使用迭代:
std::map new_map;
for(auto it=map.begin();it!=map.end();+it){
if(std::find(keys.begin(),keys.end(),it->first)!=keys.end()){
新地图。插入(*it);
}
}
//新的地图应该是{“a”,1},{“c”,3},{“d”,4}
//我希望找到的是:
new_map=map.at(键);
//产生相同的新图{{“a”,1},{“c”,3},{“d”,4}。
是否有这样一个函数,或者通常是一种比遍历整个映射并每次使用find函数更聪明的方法(我知道我可以遍历向量,但这没有多大区别,或者是吗?)

我知道我可以在向量上迭代,但这没有多大区别,或者是吗

这确实有区别,因为向量按顺序迭代通常比映射更快(向量数据在内存中是本地的,映射元素不是本地的),并且在映射中查找元素比在向量中更快(
O(log(N))
vs
O(N)
对于未排序的向量)

假设你在地图中有
M
元素,向量中有
N
键,那么你的方法是
O(M*N)
,而交换迭代和查找只能是
O(N*log(M))
。这只考虑了
find
的复杂性。考虑到迭代更复杂,因为它非常依赖于缓存

否则,我认为你的方法很好。我不知道有哪种算法能让你的代码更简洁、更富有表现力


<强> ps < /强>你可以认为这是措辞上的挑剔,但是当人们经常过度思考问题时,我会提到:“更聪明的方式”并不总是“更好的方法”。不要太聪明。大多数算法都可以用一个简单的循环来代替,但它们通常被认为比手写循环更具表现力和可读性。当手边没有解决问题的算法时,试图将某些内容压缩到算法中,通常会导致代码可读性和表达性较差。如果有人找到了一个可以在这里使用的算法,我将返回这个PS:P

< P>中的所有内容,我也会考虑使用<代码> STD::CopyIfI/<代码>算法。它不会在这里的源代码中保存太多字符,但更明确:

std::map<std::string, int> map = {{"a", 1}, {"b", 2}, {"c", 3}, {"d", 4}, {"e", 5}};
std::unordered_set<std::string> keys = {"a", "c", "d"};
std::map<std::string, int> new_map;

std::copy_if(map.begin(), map.end(),
             std::inserter(new_map, new_map.end()),
             [&keys](const auto& e){ return keys.find(e.first) != keys.end(); });

从前面的答案开始(因此在
键上迭代而不是在
映射上迭代),在我看来,“算法方式”(意思是:使用
标题中的标准算法)可能是使用
std::transform()


主题外未请求的建议:不要对“
std::map
”变量使用“
map
”(类名相同,忽略名称空间)。可能有效,没有人使用std添加
。。。但是为什么要挑战命运呢?

非常感谢,我会把这个问题留一点时间,看看是否还有其他人在接受之前有什么补充。@LeoE当然,我想先写一条评论,但时间太长了。如果有人提出一个算法,我会很感兴趣,尽管我不认为有人能打败
O(N*log(M))
@LeoE你的
键严格来说是向量吗?你能用另一个容器装吗?如果使用
std::unordered\u set
,则其查找为
O(1)
。然后总体复杂度将是
O(M)
。不,键可以是向量以外的东西。@LeoE然后,我将尝试
std::unordered_set keys={“a”、“c”、“d”}
if(keys.find(it->first)!=keys.end()…
。您是否可以不只是迭代这些键,检查该键是否存在于
map
中,如果存在,请将键值对从
map
复制到
new\u map
std::copy_if(map.begin(), map.end(),
             std::inserter(new_map, new_map.end()),
             [&keys](const auto& e){ return keys.contains(e.first); });
std::transform(keys.cbegin(), keys.cend(),
               std::inserter(new_map, new_map.end()),
               [&](auto const & k) -> std::pair<std::string, int>
                { return {k, map[k]}; });
for ( auto const & k : keys )
   new_map[k] = map[k];