C++ 优化将地图重新排列为矢量的矢量

C++ 优化将地图重新排列为矢量的矢量,c++,map,iterator,C++,Map,Iterator,我有一个包含整数值的映射。我想把这张地图重新排列成一个向量的向量,这样所有的公共元素都在一个向量内。因此,我实现了以下代码。 但问题是我的地图在两个方向上都包含大量数据。因此,我担心我的方法很慢,因为我总是擦除地图的元素。所以,我想改进这个方法。你认为删除元素是最好的方法吗。如果你知道,给我一些其他有效的方法。如果您认为我的方法仍然可以改进,请输入我的代码。我提供了一个示例数据,让您了解我的数据的外观。 我希望这个向量为每个公共元素放置一个唯一的标签。 先谢谢你 //populate my ma

我有一个包含整数值的映射。我想把这张地图重新排列成一个向量的向量,这样所有的公共元素都在一个向量内。因此,我实现了以下代码。 但问题是我的地图在两个方向上都包含大量数据。因此,我担心我的方法很慢,因为我总是擦除地图的元素。所以,我想改进这个方法。你认为删除元素是最好的方法吗。如果你知道,给我一些其他有效的方法。如果您认为我的方法仍然可以改进,请输入我的代码。我提供了一个示例数据,让您了解我的数据的外观。 我希望这个向量为每个公共元素放置一个唯一的标签。 先谢谢你

//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 11
14 15 16 17 21
25 26
期待您的建议

我担心我的方法很慢,因为我总是删除我地图上的元素

你不应该担心这个特殊的操作。从映射中擦除元素并不是一个非常昂贵的操作(
O(logn)
,与从向量中擦除相比
O(N)


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

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

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);
    }
}
typedef std::设置一个集合;
typedef std::向量所有_集合;
typedef std::映射源_数据;
源数据src;
所有(u)收集数据;;
而(!src.empty())
{
dst.推回(一个集合());
一个集合&c=dst.back();
source_data::const_迭代器const it=src.begin();
c、 插入(它->第一);
c、 插入(it->second.begin(),it->second.end());
src.擦除(it);
对于(一个集合::常量迭代器jt=c.begin(),end=c.end();jt!=end;++jt)
{
source_data::const_迭代器const kt=src.find(*jt);
如果(kt==src.end())继续;
c、 插入(kt->second.begin(),kt->second.end());
src.erase(kt);
}
}
现在,
dst
中的每个集合都应该包含一个“连接的集合”


(在C++11之前,您的迭代器可能必须是可变迭代器,因为
erase()
之前已被破坏。)

在提问时,您应该非常清楚最初的问题是什么。特别是,第一段中连接的定义是什么?映射包含什么(除了整数,它们代表什么,键是什么)?你想要向量的输出向量是什么?@David Rodríguez-dribeas:我已经修改了post位。我想让向量的向量分别使用其他部分的所有公共元素。可能是,我可以使用multy map,但我不知道如何添加另一个键,在这种情况下,该键等于我的向量的索引。问题仍然没有解决非常清晰(代码太多,但解释不够),但我的理解是,你想要构建元素集,这些元素集一起出现在地图的任何条目中,也就是说,如果
a->b,c
b->d
,那么这两个元素集应该合并到
a,b,c,d
,是吗?@DavidRodríguez dribeas:我回滚了你的编辑,我希望没问题,因为尽管g_niro的因维特为了修改他的代码,我认为在问题本身中对代码进行实质性修改不是一个好主意。(毕竟,它不再是同一个问题!)Rukh:代码完全等价,我只是重新排列变量的定义,以便更接近使用,因此避免来回。代码没有实质性的改变,因为编译器会为两个版本生成相同的代码谢谢,我使用DEV C++。我希望,可以用Dev.othe实现这个代码。r比集合的向量,这个搜索条件比我的搜索方法快吗?请告诉我。因为我喜欢这样做way@g_niro:是的,它更快,因为
set
按值查找比
vector
更快。不过,如果您愿意,您可以随时将结果集复制回vector中。谢谢您提供的代码。另外,我想知道你的元素搜索策略(查找并继续),因为它和我的有点不同。我想你的方式也更快。是吗?
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);
    }
}