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