如何迭代地图,修改地图但在每次迭代时恢复?

时间:2010-08-23 22:17:12

标签: c++ stl map iterator

我有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);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

我认为std :: advance可能会有所帮助。创建temp,然后前进begin()直到你现在的位置(找到std :: distance)......然后你正在尝试做什么。

答案 1 :(得分:0)

通过代码,我了解你现在的目标。我建议的第一种方式就是这样做:每次通过外部循环,制作current_partition数据结构的临时副本,然后对其进行处理,最后将其丢弃。

你说过这个问题就是你不能在原始地图中使用迭代器来找到你应该处理的元素。确实如此;你不能直接这样做。但它是地图。您正在处理的元素将具有,它在数据结构的任何副本中都是相同的,因此您可以使用它来创建您应该处理的元素的迭代器在副本中。

例如:

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);
            }
        }
    }
}