2016-04-28 28 views
0

文字のリストがあり、連続した重複を削除しようとしています。 {'a', 'b', 'a', 'a', 'a'}{'a', 'b', 'a'}になります。最後の 'a'を取り除くときには、itr2は何も指さず、「リストイテレーターは逆参照できない」というエラーが出ます。私はこれがなぜ起こるのか理解していますが、私はそれを解決するのが難しいです。どのようにこれを解決することができ、これを行うためのより良い方法がありますか?ここで反復処理中にリスト内の最後の要素を削除すると、エラーが発生する

は私のコードです:

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

答えて

3

声明

itr2 = next(itr, 1); 

はあなたにendイテレータを与えるかもしれないあなたは

のような、それを間接参照

何かをしようとする前に、あなたがそれをチェックしなければなりません

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

おかげ作業、これは完璧です。 – Moose

3

uniqueと呼ばれる連続する重複を削除する関数がすでにリストにあります。

myList.unique(); 

更新

、あなたはuniqueのアルゴリズムのバージョンを使用することができ、ケーシングを無視します。

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

ありがとうございますが、ケーシングを無視する必要があります – Moose

+0

ハンドルケースに更新されました。 –

0

より単純なC++ 11ソリューションです。これを解決するには、2ではなく1つのイテレータを使用します。myList.eraseをイテレータ自体に割り当てます。これにより、現在の要素が削除され、イテレータが前方に移動します。

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

ideone例here

+0

これはより洗練されていますが、技術的には、まだ 'next()'から返されたイテレータを使用するOPのように、 'std :: prev()'から返される別のイテレータを使用しています。 –

関連する問題