有条件地将贴图关键帧复制到向量

Conditionally copy map keys to a vector

本文关键字:复制 向量 关键帧 有条件      更新时间:2023-10-16

我有一个映射容器。我想把它的所有键和用户指定的第一个字母复制到一个向量。如何以有效的方式做到这一点?非常感谢。

std::map(std:string, size_t) myMap;
myMap.insert(std:make_pair("Ace", 11);
myMap.insert(std:make_pair("Ape", 12);
myMap.insert(std:make_pair("Age", 13);
myMap.insert(std:make_pair("Beat", 21);
myMap.insert(std:make_pair("Boat", 22);
myMap.insert(std:make_pair("Boss", 23);
myMap.insert(std:make_pair("Coat", 31);
myMap.insert(std:make_pair("Cost", 32);
myMap.insert(std:make_pair("Cast", 33);

例如,如果我想从myMap中提取所有以"Bo"开头的键的元素,并将满意的结果填充到myVec,那么myVec将具有以下元素:

Boat
Boss

为简洁起见省略的声明:

begin = myMap.lower_bound("Bo");
end = std::find_if(begin, myMap.end(), first_does_not_begin_with("Bo"));
for (i=begin; i!=end; ++i)
    myVec.push_back(i->first);

你可以实现first_does_not_begin_with函子类,对吧?操作员应具有以下签名:

bool operator()(std::pair<const std::string, size_t> const &);

如果可以假设表示字符串的字母是连续的并且如果"one-past-z"仍然是有效的字符串字符,则可以使用对lower_boundtransform的两个调用,这两个调用的范围都在向量中。

const_iterator start = myMap.lower_bound("Bo");
const_iterator finish = myMap.lower_bound("Bp");  // "Bo" with the last digit incremented by 1
struct Transformer
{
    mapKey operator()(const myMapType::value_type& item)
    {
        return item.first;
    }
}
vector<mapKey> output;
std::transform(start, finish, std::back_inserter(output), Transformer());

除了myMap,您还可以保留一个multimap,它将以两个字母的字符串作为关键字,并以原始映射的迭代器作为值。map::insert返回一个迭代器(通过pair(,您可以将其放入multimap对象中。

每当您需要高效地搜索2个字母的键时,只需查找multimap,即可获得原始映射的迭代器并使用它们。

multimap对象只不过是原始地图上的索引,这是数据库系统中使用的一种想法。重要的是要知道原始map中应该有大量的项,否则使用multimap作为索引器就没有那么有利了。

我的解决方案:

std::string token = "Bo"; //first few letters
std::vector<std::string> myVec;
for(std::map<std::string,size_t>::iterator i=myMap.begin();i!=myMap.end();i++)
{
       if ( token == i->first.substr(0, token.size()) )
               myVec.push_back(i->first);
}
for(std::vector<std::string>::iterator i=myVec.begin();i!=myVec.end();i++ )
      std::cout << *i << std::endl;

输出:

Boat
Boss

完整演示:http://www.ideone.com/03cps


如果你喜欢<algorithm><iterator>,那么你可以这样做:

std::vector<std::string> myVec=std::for_each(myMap.begin(),myMap.end(),collector("Bo"));
std::ostream_iterator<std::string> oiterator(std::cout, "n");
std::copy(myVec.begin(), myVec.end(), oiterator);

输出:

Boat
Boss

函子collector实现为:

struct collector
{
   std::string token;
   std::vector<std::string> keys;
   collector(const std::string & token) : token(token) {}
   void operator()(const std::pair<std::string,size_t> &p)
   {
        if ( token == p.first.substr(0, token.size()) )
               keys.push_back(p.first);
   }
   operator std::vector<std::string>() { return keys; }
};

完整演示:http://www.ideone.com/U1299