有条件地将地图键复制到矢量

时间:2011-07-16 05:14:30

标签: c++ vector map copy

我有一个地图容器。我想用用户指定的第一个字母将其所有键复制到矢量。如何以有效的方式做到这一点?谢谢!

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

4 个答案:

答案 0 :(得分:1)

为简洁而遗漏了声明:

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 &);

答案 1 :(得分:1)

IF 你可以假设表示字符串的字母是连续的,“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());

答案 2 :(得分:0)

我的解决方案:

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

答案 3 :(得分:0)

myMap一起,您还可以保留multimap,其中包含2个字母的字符串作为键,并将原始地图的迭代器作为值。 map::insert返回一个迭代器(通过pair),您可以将其放入multimap对象中。

每当您需要有效搜索2个字母的密钥时,只需查找multimap,获取原始地图的迭代器并使用它们。

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