remove_if, эквивалентный для станд.:: карта

Я просто конвертирую ответ Liquki в команды Ubuntu. В системе на основе Ubuntu это работает!:

sudo apt -y install python-pip
pip install -U pip
sudo pip install -U setuptools
113
задан aJ. 29 April 2009 в 05:05
поделиться

7 ответов

Почти.

for(; iter != endIter; ) {
     if (Some Condition) {
          aMap.erase(iter++);
     } else {
          ++iter;
     }
}

То, что у вас изначально было, увеличило бы итератор в два раза , если бы вы удалили из него элемент; потенциально вы можете пропустить элементы, которые нужно было стереть.

Это распространенный алгоритм, который я видел, использовался и документировался во многих местах.

[EDIT] Вы правы, что итераторы становятся недействительными после стирания, но только итераторы, ссылающиеся на удаляемый элемент, другие итераторы по-прежнему действительны. Следовательно, используя iter ++ в вызове erase () .

108
ответ дан 24 November 2019 в 02:43
поделиться

Вот некоторое изящное решение.

for (auto it = map.begin(); it != map.end();)
{   
    (SomeCondition) ? map.erase(it++) : (++it);
}
1
ответ дан 24 November 2019 в 02:43
поделиться

From the bottom notes of:

http://www.sgi.com/tech/stl/PairAssociativeContainer.html

a Pair Associative Container cannot provide mutable iterators (as defined in the Trivial Iterator requirements), because the value type of a mutable iterator must be Assignable, and pair is not Assignable. However, a Pair Associative Container can provide iterators that are not completely constant: iterators such that the expression (*i).second = d is valid.

1
ответ дан 24 November 2019 в 02:43
поделиться

Я получил эту документацию из превосходной ссылки SGI STL :

Карта имеет важное свойство, которое вставка нового элемента в карту не делает недействительными итераторы, которые указать на существующие элементы. Стирание элемент из карты также не признать недействительными любые итераторы, кроме Конечно, для итераторов, которые на самом деле указать на элемент, который в настоящее время стерты.

Итак, имеющийся у вас итератор, указывающий на элемент, который нужно стереть, будет, конечно, недействительным. Сделайте что-то вроде этого:

if (some condition)
{
  iterator here=iter++;
  aMap.erase(here)
}
3
ответ дан 24 November 2019 в 02:43
поделиться

IMHO не существует эквивалента remove_if () .
Вы не можете изменить порядок карты.
Итак, remove_if () не может поместить ваши пары интересов в конец, на котором вы можете вызвать erase () .

1
ответ дан 24 November 2019 в 02:43
поделиться

Steve Folly's answer I feel the more efficient.

Here is another easy-but-less efficient solution:

The solution uses remove_copy_if to copy the values we want into a new container, then swaps the contents of the original container with those of the new one:

std::map<int, std::string> aMap;

...
//Temporary map to hold the unremoved elements
std::map<int, std::string> aTempMap;

//copy unremoved values from aMap to aTempMap
std::remove_copy_if(aMap.begin(), aMap.end(), 
                    inserter(aTempMap, aTempMap.end()),
                    predicate);

//Swap the contents of aMap and aTempMap
aMap.swap(aTempMap);
0
ответ дан 24 November 2019 в 02:43
поделиться

Первая

Карта имеет важное свойство: вставка нового элемента в карту не делает недействительными итераторы, указывающие на существующие элементы. Удаление элемента из карты также не делает недействительными итераторы, за исключением, конечно, итераторов, которые фактически указывают на удаляемый элемент.

Во-вторых, следующий код хорош

for(; iter != endIter; )
{
    if(Some Condition)
    {
        aMap.erase(iter++);
    }
    else
    {
        ++iter;
    }
}

При вызове функции параметры оцениваются перед вызовом этой функции.

Итак, когда iter ++ оценивается перед вызовом для удаления, оператор ++ итератора вернет текущий элемент и укажет на следующий элемент после вызова.

1
ответ дан 24 November 2019 в 02:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: