如何遍历地图,修改地图但在每次迭代时恢复?
Posted
技术标签:
【中文标题】如何遍历地图,修改地图但在每次迭代时恢复?【英文标题】:How to iterate through map, modify map but restore at each iteration? 【发布时间】:2010-08-23 22:17:12 【问题描述】:我有一个std::map<int,int>
,我们称之为my_map
我使用迭代器和 for 循环遍历这个映射。
在每次迭代中,我想修改此映射中的许多元素,但将其再次恢复为原始值以供循环的下一次迭代使用。
我以为我可以创建迭代器 my_temp_map
的临时副本,但是我无法使用迭代器找到我应该处理的元素。
然后我想我可以创建一个临时副本,在原点 my_map
上工作,并在每个循环结束时将原始副本恢复到临时副本。但是我相信这会使迭代器无效,因为分配会删除所有元素
如何解决这个问题?
已添加代码
所以每个内部循环都会修改 current_partition(并且还有一些缺少的代码将存储修改后的 current_partition 的结果),但是在每个 inner_loop 之后我需要将 current_loop 恢复到它以前的自我。
std::map<int,int> current_partition = bitset_to_map(centre->second->bit_partitions);
int num_parts = (std::max_element(current_partition.begin(), current_partition.end(),value_comparer))->second;
for (std::map<int,int>::iterator itr = current_partition.begin(); itr != current_partition.end(); ++itr)
for (int next_part = 0; next_part<num_parts+1; ++next_part)
if (next_part != itr->second)
int current_part = itr->second;
itr->second = next_part;
std::vector<int> first_changed_part, last_changed_part;
for (std::map<int,int>::iterator new_itr = current_partition.begin(); new_itr != current_partition.end(); ++new_itr)
if (new_itr->second == current_part)
first_changed_part.push_back(new_itr->first);
if (new_itr->second == next_part)
last_changed_part.push_back(new_itr->first);
【问题讨论】:
你的问题没有多大意义。整个前提有点奇怪(您正在修改一堆数据然后丢弃它?),但主要问题是您一直在说“迭代器”并且不清楚您指的是哪些迭代器。在您的第一个示例中,您当然可以在my_temp_map
中使用迭代器来做您想做的事情——您是在谈论其他迭代器吗?在第二个示例中,您担心哪些迭代器会失效?一些代码(或伪代码)在这里可能会有所帮助。
【参考方案1】:
我认为 std::advance 可能会有所帮助。创建临时文件,然后推进 begin() 直到你现在所在的位置(通过 std::distance 找到)......然后无论你想要做什么。
【讨论】:
或者,如果您不需要更改当前迭代器位置之前的项目,您可以创建仅包含从当前位置到末尾的元素的临时映射(使用构造函数迭代器作为参数)。【参考方案2】:有了代码,我明白你现在要做什么了。我会按照您建议的第一种方式进行操作:每次通过外循环时,制作current_partition
数据结构的临时副本,然后处理它,最后将其丢弃。
你说这样做的问题是你不能在原始地图中使用迭代器来找到你应该处理的元素。确实如此;你不能直接这样做。但它是一个地图。您正在处理的元素将有一个 key,它在数据结构的任何副本中都是相同的,因此您可以使用它来为您应该处理的元素创建一个迭代器在副本中。
例如:
std::map<int,int> current_partition = bitset_to_map(centre->second->bit_partitions);
int num_parts = (std::max_element(current_partition.begin(), current_partition.end(),value_comparer))->second;
for (std::map<int,int>::iterator itr = current_partition.begin(); itr != current_partition.end(); ++itr)
// Make a temporary copy of the map. Iterators between the original and the copy aren't
// interchangeable, but the keys are.
std::map<int,int> tmp_current_partition = current_partition;
// Use the iterator itr to get the key for the element you're working on (itr->first),
// and then use that key to get an equivalent iterator into the temporary map using find()
std::map<int,int>::iterator tmp_itr = tmp_current_partition.find(itr->first);
// Then just replace current_partition with tmp_current_partition and
// itr with tmp_itr in the remainder (hopefully I didn't miss any)
for (int next_part = 0; next_part<num_parts+1; ++next_part)
if (next_part != tmp_itr->second)
int current_part = tmp_itr->second;
tmp_itr->second = next_part;
std::vector<int> first_changed_part, last_changed_part;
for (std::map<int,int>::iterator new_itr = tmp_current_partition.begin(); new_itr != tmp_current_partition.end(); ++new_itr)
if (new_itr->second == current_part)
first_changed_part.push_back(new_itr->first);
if (new_itr->second == next_part)
last_changed_part.push_back(new_itr->first);
【讨论】:
以上是关于如何遍历地图,修改地图但在每次迭代时恢复?的主要内容,如果未能解决你的问题,请参考以下文章