2011-06-21 59 views
15

我現在有for循環以下:迭代對於第二到最後一個元素列表中的

for(list<string>::iterator jt=it->begin(); jt!=it->end()-1; jt++) 

我有字符串這是一個更大的列表(list<list<string> >)的列表。我想遍歷內部列表的內容,直到到達第二個到最後一個元素。這是因爲我已經處理了最後一個元素的內容,沒有理由再次處理它們。

但是,使用it->end()-1是無效的 - 我不能在這裏使用-運算符。雖然我可以使用運算符--,但這會在每個循環中遞減最後的迭代器。

我相信一個STL列表是一個雙向鏈表,所以從我的角度來看,應該可以做到這一點。

建議?在此先感謝

回答

9

使用標準庫所需的建議:

std::for_each(lst.begin(), --lst.end(), process); 

如果你不想創建一個仿函數[我幾乎沒做]費盡口舌,而不能使用反向迭代器,葫蘆結束檢查出循環:

for(iterator i = lst.begin(), j = --lst.end(); i != j; ++i) { 
    // do 
    // stuff 
} 

或者,你可以信任優化承認,它沒有繼續重建結束條件,並做了提升本身。它的可靠程度取決於列表實現,循環代碼的複雜程度以及優化器的性能。

無論如何,只要做一件最容易理解的事情,並在完成後擔心性能。

+0

我很欣賞這個解決方案的簡單性。是的,使用反向迭代器的其他解決方案非常好 - 但是您的解決方案在不使用特殊迭代器的情況下教會了我一種方法。 – BSchlinker

+0

「如果你不想爲創建一個仿函數而煩惱」 - 今天我會建議只在那裏粘貼一個lambda – Paladin

6

列表迭代器不是隨機迭代器。你應該做到以下幾點:

if (! it->empty()) 
{ 
    list<string>::iterator test = it->end(); 
    --test; 
    for(list<string>::iterator jt = it->begin(); jt != test; ++jt) 
    { 
    ... 
    } 
} 

一件事:使用++jtjt++jt++源代碼通常看起來是這樣的:

iterator operator++ (int i) 
{ 
    iterator temp = (*this); 
    ++(*this); 
    return temp; 
}; 
4

雖然我可以使用 - 運營商,這將減小在每個週期這最後的迭代器。

不,它不會。它會得到一個複製結束迭代器並將其遞減。就這樣。它不會更改存儲在列表中的結束迭代器。

您的主要問題應該是驗證列表是而不是爲空,從而確保存在--it-> end()。

4

逆向迭代器呢?

for(list<string>::reverse_iterator jt=++(it->rbegin()); jt!=it->rend(); jt++) 
+0

這實際上是由於使用了「!」會導致錯誤運算符在語句「jt!= it-> rend();」 – BSchlinker

+0

該類型應該是'list :: reverse_iterator',而不僅僅是'list :: iterator'。 –

+0

不知道反向迭代器 - 謝謝! – BSchlinker

1

在C++ 11後,最好的答案似乎是對http://en.cppreference.com/w/cpp/iterator/prev說使用std::prev

for(iterator i = lst.begin(); i != std::prev(lst.end()); ++i) { 
    // do 
    // stuff 
} 

的文檔的std ::分組,

雖然表達 - c.end()經常編譯,但不保證這樣做:c.end()是一個右值表達式,並且沒有迭代器要求指定右值的遞減保證工作。特別是,當迭代器實現爲指針時,--c.end()不會編譯,而std :: prev(c.end())會執行。

相信的std ::上一個()的空名單上是不確定的,所以你可能需要在!i.empty()條件來包裝這個

相關問題