优化将地图重新​​排列成矢量矢量

时间:2011-11-30 12:17:06

标签: c++ map iterator

我有一个包含整数值的地图。我想将这个地图重新排列成一个矢量矢量,这样所有的常见元素都在一个矢量中。所以,我已经实现了以下代码。 但问题是我的地图包含两个方向的巨大数据列表。所以,我担心我的方法很慢,因为我总是擦除我的地图元素。所以,我想改进这种方法。你认为擦除元素是最好的方法吗?如果你知道,给我一些其他有效的方法。如果您认为我的方法仍然可以改进,请修改我的代码。我已经提供了一个示例数据,我的数据看起来如何让您了解。 我希望这个向量向量为每个公共元素添加一个唯一的标签。 提前谢谢你。

//populate my map from the upper part of my program

vector<int> list;
vector<vector<int> > listoflist;
map<int,vector<int> >::iterator it;
vector<int>::const_iterator any, is_in;

while (!my_map.empty()){
         it = my_map.begin();
         list.push_back(it->first);
         list.insert(list.end(), (it->second).begin(), (it->second).end());
         my_map.erase(it); // erase by iterator
         //go to next key and take its elements, if one is not inside add into list
         int newsize = list.size();
         for (int next=1; next<newsize; next++){          
              vector<int>& neb_to_next_element = my_map[list[next]];                
              for (any=neb_to_next_element.begin();
                     any!=neb_to_next_element.end(); any++){            
                   is_in = find (list.begin(), list.end(), *any);           
                   if(is_in==list.end()) list.push_back(*any);
              }
              //remove next now
              my_map.erase(list[next]);
              newsize = list.size();      
         }
         listoflist.push_back(list);
         list.clear();
}

这是我地图的一部分

5 7 9
7 5 9 11
9 5 7 11
11 7 9
14 15 16 17
15 14 17
16 14 17 21
17 14 15 16 21
21 16 17
25 26
26 25

我想要一个矢量矢量,如下所示

5 7 9 11
14 15 16 17 21
25 26

期待你的建议。

2 个答案:

答案 0 :(得分:0)

  

我担心我的方法很慢,因为我一直在擦除地图的元素。

你不应该担心这个特殊的操作。从地图中删除元素并不是一项非常昂贵的操作(O( log N ),与从矢量O(N)中删除相比。)

另一方面,还有其他可以改进的操作,例如,构建中间集而不是在list向量中查找元素是否仍然存在。集合中的查找为O(log N),而向量中的查找为O(N)。这是理论上的复杂性,好像元素的数量相当小,隐藏的常量可能会改变平衡(在一个集合中,每个插入的元素都有一个动态分配,而在向量中只有一些重新分配,这意味着如果N很小,矢量查找的线性时间可以通过较少量的动态分配来补偿。

答案 1 :(得分:0)

如何为输出创建集合向量:

typedef std::set<int>                   one_collection;
typedef std::vector<one_collection>     all_collections;
typedef std::map<int, std::vector<int>> source_data;

source_data     src;
all_collections dst;

while (!src.empty())
{
    dst.push_back(one_collection());
    one_collection & c = dst.back();

    source_data::const_iterator const it = src.begin();

    c.insert(it->first);
    c.insert(it->second.begin(), it->second.end());

    src.erase(it);

    for (one_collection::const_iterator jt = c.begin(), end = c.end(); jt != end; ++jt)
    {
        source_data::const_iterator const kt = src.find(*jt);

        if (kt == src.end()) continue;

        c.insert(kt->second.begin(), kt->second.end());
        src.erase(kt);
    }
}

现在dst中的每个集合都应包含一个“连接集合”。

(Pre-C ++ 11你的迭代器可能必须是可变迭代器,因为先前已经破坏了erase()。)