Как перебирать карту, модифицировать карту, но восстанавливать на каждой итерации? - PullRequest
1 голос
/ 24 августа 2010

У меня есть 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 ]

1 голос
/ 24 августа 2010

Я думаю, что std :: advance может помочь. Создайте temp, затем продвигайте begin () до тех пор, пока вы не окажетесь там, где вы сейчас находитесь (это выясняется с помощью std :: distance) ... затем все, что вы пытаетесь сделать.

0 голосов
/ 24 августа 2010

С кодом я понимаю, что вы собираетесь сейчас.Я бы сделал это в основном первым предложенным вами способом: каждый раз во внешнем цикле делайте временную копию структуры данных 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);
            }
        }
    }
}
...