如何在multimap中更改字符串

时间:2014-04-25 22:05:56

标签: c++ c++11

我有多图:

multimap<string, vector<object> > myMultimap;

我需要更改已创建的多图的部分字符串。

it-&gt; first = newString;

不起作用....

4 个答案:

答案 0 :(得分:2)

如果您需要使用该键“更改”所有元素的键:

template<typename Key, typename ValueType, typename Compare,
         typename Allocator, typename FromKey, typename ToKey>
auto change_key(std::multimap<Key, ValueType, Compare, Allocator>& m,
                FromKey const& from_raw, ToKey const& to_raw)
-> typename std::multimap<Key, ValueType, Compare, Allocator>::iterator
{
    Key const& from = from_raw; // convert once only, not in each iteration
    Key const& to = to_raw;

    auto hint = m.lower_bound(to);
    auto const itsFrom = m.equal_range(from);
    for(auto cur = itsFrom.first; cur != itsFrom.second; ++cur)
    {
        hint = m.emplace_hint(hint, to, std::move(cur->second));
    }
    m.erase(itsFrom.first, itsFrom.second);
    return hint;
}

在C ++ 1y中,如果比较函数对象是透明的,您可能希望将显式转换放到fromto

我不太确定我是否正确使用lower_bound作为提示;标准(n3797)说明了表102中的提示p - 关联容器要求(除了容器):

  

元素尽可能靠近p之前的位置插入。

和复杂性:

  

一般情况下是对数,但如果在p

之前插入元素,则摊销常数

所以我们需要在插入点之后的位置;我不确定插入点本身是否是一个有用的提示。对我来说,这似乎建议使用upper_bound,因为它总是返回一个键大于搜索键的位置;另一方面,我一直在寻找建议使用lower_bound的答案。

用法示例:

#include <map>
#include <vector>
#include <iostream>
#include <string>

struct object
{
    int m;
};

std::ostream& operator<<(std::ostream& o, object const& p)
{
    return o << p.m;
}

template<typename V>
std::ostream& operator<<(std::ostream& o, std::vector<V> const& v)
{
    for(auto const& e : v) o << e;
    return o;
}

template<typename K, typename V>
std::ostream& operator<<(std::ostream& o, std::multimap<K, V> const& m)
{
    for(auto const& p : m) o << "["<<p.first<<" : "<<p.second<<"], ";
    return o;
}

int main()
{
    auto make_vector = [](int p) { return std::vector<object>{{p}}; };
    std::multimap<std::string, std::vector<object>> myMultimap =
    {{
          {"1st", make_vector(0)}
        , {"1st", make_vector(1)}
        , {"1st", make_vector(2)}
        , {"2nd", make_vector(3)}
        , {"2nd", make_vector(4)}
        , {"2nd", make_vector(5)}
        , {"3rd", make_vector(6)}
        , {"3rd", make_vector(7)}
        , {"3rd", make_vector(8)}
    }};

    std::cout << myMultimap;

    change_key(myMultimap, "2nd", "4th");

    std::cout << "\n\n" << myMultimap;
}

答案 1 :(得分:1)

您无法更改地图/多图的键,因为它是一个常量值。另一种方法是找到要替换的键,删除它并插入新值:

typedef multimap<string, vector<object> > Multimap;
Multimap myMultimap;
// ...
Multimap::iterator item_pos = myMultimap.find("some value");
if(item_pos != myMultimap.end())
{
    vector<object> key_value = item_pos->second;
    myMultimap.erase(item_pos);
    myMultimap.insert(Multimap::value_type("new value", key_value));
}

答案 2 :(得分:1)

你不能只是“更改”这样一个键,你必须为记录创建一个新条目,并删除旧条目:

multimap<string, vector<object> > myMultimap;
...
myMultimap.insert(std::make_pair(newString, it->second));
myMultimap.erase(it);

答案 3 :(得分:0)

鉴于:

“我有一个多图”和

“我需要更改密钥而不是数据”

答案是:

“您选择了错误的数据结构 - 是时候重新考虑解决方案了”