C++中迭代器筆記
目的:為了統一遍歷容器的操作,無序容器中同樣可以使用迭代器,順序則由實現此容器的對應資料結構的原理決定
迭代器的begin指向容器的第一個元素,end指向容器的最後一個元素的後一個元素
讓我們一步一步解說迭代器的用法,最原始的用法:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
return 0;
}
我們用std::vector
後來,可以用auto來定義一個迭代器,會自動識別容器的資料型別,定義對應的迭代器
這裡的it可以理解為一個指標,這個*代表了指標指向的內容(即解引)
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
return 0;
}
離譜的來了,auto在不同的環境中的用法完全不一樣
在傳統的迭代器迴圈中,比如:
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
這裡 it
是迭代器,需要使用 *it
來獲取迭代器指向的元素。
而在範圍-based for 迴圈中:
for (const auto& it : vec) {
std::cout << it << " ";
}
這裡的it不是迭代器了,就是auto,原來C++這麼智慧,那我剛剛看了半天迭代器是在幹啥我草
不對勁,剛剛又看了一些內容,在查詢一個元素時,find的本質要麼是一棵平衡二叉樹(針對有序的set或者map),複雜度是logn,要麼是1(針對無序的set或者map);而auto這麼遍歷的複雜度是n,所以在遍歷時,用const auto&是沒問題的,但是查詢元素時還是用迭代器和find的組合更快。
大徹大悟了,如果只需要判斷一個元素是否出現過,用unordered+find,透過雜湊表可以把速度最佳化到1