如果值等于键,则合并映射中的条目

时间:2019-04-11 08:42:20

标签: c++ stdmap

我有一个具有以下值的std :: map:

  

2 31
  4 36
  5 29
  6 24
  24 49
  25 83
  29 63
  36 42
  42 79

现在,如果某个值存在键,我想“合并”值。 因此,所需的输出(与数据结构无关)将是:

  

2 31
    4 36 42 79
    5 29 63
    6 24 49
    25 83

我尝试遍历地图,并对每个值使用std :: find。但是我遇到的矢量大小大于3的问题,对于大型地图来说似乎很慢。这是一个没有给出准确输出的小例子:

int main(int argc, char** argv)
{   
    std::map<int, int> my_map = { {2, 31}, {4, 36}, {5, 29}, {6, 24}, {24, 49}, {25, 83}, {29, 63}, {36, 42}, {42, 79} };

    std::vector<int> temp_vec;
    std::vector<std::vector<int>> destination_vec;

    for (auto it = my_map.begin(); it != my_map.end(); ++it) {

        std::map<int, int>::iterator map_iterator = my_map.find(it->second);
        if (map_iterator == my_map.end()) {
            temp_vec.push_back(it->first);
            temp_vec.push_back(it->second);
        }
        else {
            temp_vec.push_back(it->first);
            temp_vec.push_back(it->second);
            temp_vec.push_back(map_iterator->second);
            // I stopped here because I could try another if loop here or a while loop for the whole process but it seems very inefficient
        }
        destination_vec.push_back(temp_vec);
        temp_vec.clear();
    }
}   

1 个答案:

答案 0 :(得分:3)

假设地图不能链接较小的值(如{{1, 42},{2, 1}})。

您可以使用:

std::map<int, std::vector<int>> foo(std::map<int, int> m)
{
    std::map<int, std::vector<int>> res;

    while (!m.empty())
    {
        auto it = m.begin();
        const auto key = it->first;
        auto& v = res[key];

        while (it != m.end()) {
            auto value = it->second;
            v.push_back(value);
            m.erase(it);
            it = m.find(value);
        }
    }
    return res;
}

Demo

复杂度为O(n log n)