2016-04-28 12 views
0

Ich habe eine Liste von Zeichen und ich versuche, fortlaufende Duplikate zu entfernen, z. {'a', 'b', 'a', 'a', 'a'} wird {'a', 'b', 'a'}. Beim Entfernen der letzten 'a' itr2 Punkte zu nichts und ich bekomme einen Fehler "list iterator nicht dereferencable". Ich verstehe, warum das passiert, aber ich habe Schwierigkeiten, es zu lösen. Wie kann das gelöst werden und gibt es dafür bessere Möglichkeiten?Entfernen des letzten Elements in der Liste während der Iteration verursacht Fehler

Hier ist mein Code:

void removeDuplicates(list<char> &myList) 
{ 
    list<char>::iterator itr; 
    list<char>::iterator itr2; 
    for (itr = myList.begin(); itr != myList.end();) 
    { 
     itr2 = next(itr, 1); 
     if (tolower(*itr) == tolower(*itr2)) 
     { 
      myList.erase(itr2); 
     } 
     else 
     { 
      ++itr; 
     } 
    } 
} 

Antwort

3

Die Aussage

itr2 = next(itr, 1); 

könnte Ihnen die end Iterator Sie das überprüfen müssen, bevor Sie zu dereferenzieren

So etwas wie

versuchen
if (itr2 != mylist.end() && tolower(*itr) == tolower(*itr2)) { ... } 
+0

Danke, das ist perfekt. – Moose

3

Es gibt bereits eine Funktion in der Liste, die fortlaufende Duplikate namens unique entfernt.

myList.unique(); 

aktualisieren:

Gehäuse zu ignorieren, dann können Sie den Algorithmus-Version von unique verwenden.

auto end = std::unique(s.begin(), s.end(), [](char l, char r) 
{ 
    return tolower(l) == tolower(r) 
}); 
+0

Danke, aber ich muss auch ignorieren Gehäuse – Moose

+0

aktualisiert, um Fall zu behandeln. –

0

Eine einfachere C++ 11-Lösung. Sie können dies lösen, indem Sie einen Iterator anstelle von 2 verwenden. Weisen Sie myList.release einfach dem Iterator selbst zu. Dies würde das aktuelle Element löschen und den Iterator vorwärts bewegen.

void removeDuplicates(list<char> &myList) 
{ 
    list<char>::iterator itr; 

    for (itr = myList.begin(); itr != myList.end();) 
    { 
    if (tolower(*itr) == tolower(*std::prev(itr))) 
    { 
     itr = myList.erase(itr); 
    } 
    else 
    { 
     ++itr; 
    } 
    } 
    for (itr : myList) 
    cout << itr <<" "; 
} 

Arbeiten ideone Beispiel here

+0

Obwohl dies sauberer ist, verwenden Sie technisch noch einen anderen Iterator, der von 'std :: prev()' zurückgegeben wird, genauso wie OP den Iterator verwendet, der von 'next()' zurückgegeben wird –

Verwandte Themen