From 97dc4c3881454fae16ec1659e279ae988326eea7 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Fri, 7 Feb 2025 13:01:11 -0500 Subject: [PATCH] move iterators examples here --- lectures/09_iterators_linked_lists/README.md | 143 +++++++++++++++++-- 1 file changed, 133 insertions(+), 10 deletions(-) diff --git a/lectures/09_iterators_linked_lists/README.md b/lectures/09_iterators_linked_lists/README.md index 2755f3e..5aae825 100644 --- a/lectures/09_iterators_linked_lists/README.md +++ b/lectures/09_iterators_linked_lists/README.md @@ -65,12 +65,8 @@ vector::iterator p; vector::const_iterator q; ``` defines two (uninitialized) iterator variables. An iterator is used to modify the elements of the container. A const_iterator is used when you want to traverse the elements of the container without modifying them. -- The dereference operator is used to access the value stored at an element of the container. The code: -```cpp -p = enrolled.begin(); -*p = "012312"; -``` -changes the first entry in the *enrolled* vector. + +- The dereference operator is used to access the value stored at an element of the container. - We can use arrow and the dot operator like this: ```cpp @@ -91,7 +87,134 @@ enrolled.erase(enrolled.begin() + 5); - For most containers (other than vectors), these “random access” iterator operations are not legal and therefore prevented by the compiler. The reasons will become clear as we look at their implementations. -## 9.6 A New Datatype: The list Standard Library Container Class +## 9.6 Iterator Operation Examples + +- An iterator type is defined by each STL container class. For example: + +```cpp +std::vector::iterator v_itr; +std::list::iterator l_itr; +std::string::iterator s_itr; +``` + +- An iterator is assigned to a specific location in a container. For example: + +```cpp +v_itr = vec.begin() + i; // i-th location in a vector +l_itr = lst.begin(); // first entry in a list +s_itr = str.begin(); // first char of a string +``` + +*Note*: We can add an integer to vector and string iterators, but not to list iterators. + +- The contents of the specific entry referred to by an iterator are accessed using the * dereference operator: +In the first and third lines, *v itr and *l itr are l-values. In the second, *s_itr is an r-value. + +```cpp +*v_itr = 3.14; +cout << *s_itr << endl; +*l_itr = "Hello"; +``` + +- Stepping through a container, either forward and backward, is done using increment (++) and decrement (--) +operators: + +```cpp +++itr; itr++; --itr; itr--; +``` + +These operations move the iterator to the next and previous locations in the vector, list, or string. The +operations do not change the contents of container! + +- Finally, we can change the container that a specific iterator is attached to as long as the types match. +Thus, if v and w are both std::vector, then the code: + +```cpp +v_itr = v.begin(); +*v_itr = 3.14; // changes 1st entry in v +v_itr = w.begin() + 2; +*v_itr = 2.78; // changes 3rd entry in w +``` + +works fine because v_itr is a std::vector<double>::iterator, but if *a* is a std::vector<std::string> then + +```cpp +v_itr = a.begin(); +``` + +is a syntax error because of a type clash! + +## 9.7 Additional Iterator Operations for Vector (& String) Iterators + +- Initialization at a random spot in the vector: + +```cpp +v_itr = v.begin() + i; +``` +Jumping around inside the vector through addition and subtraction of location counts: + +```cpp +v_itr = v_itr + 5; +``` +moves p 5 locations further in the vector. These operations are constant time, O(1) for vectors. +- These operations are not allowed for list iterators (and most other iterators, for that matter) because of the +way the corresponding containers are built. These operations would be linear time, O(n), for lists, where n is +the number of slots jumped forward/backward. Thus, they are not provided by STL for lists. +- Students are often confused by the difference between iterators and indices for vectors. Consider the following +declarations: + +```cpp +std::vector a(10, 2.5); +std::vector::iterator p = a.begin() + 5; +unsigned int i=5; +``` + +- Iterator p refers to location 5 in vector a. The value stored there is directly accessed through the * operator: + +```cpp +*p = 6.0; +cout << *p << endl; +``` + +- The above code has changed the contents of vector a. Here’s the equivalent code using subscripting: + +```cpp +a[i] = 6.0; +cout << a[i] << endl; +``` + +- Here’s another common confusion: + +```cpp +std::list lst; lst.push_back(100); lst.push_back(200); +lst.push_back(300); lst.push_back(400); lst.push_back(500); +``` + +```cpp +std::list::iterator itr,itr2,itr3; +itr = lst.begin();// itr is pointing at the 100 +++itr; // itr is now pointing at 200 +*itr += 1; // 200 becomes 201 +// itr += 1; // does not compile! can't advance list iterator like this +``` +```cpp +itr = lst.end(); // itr is pointing "one past the last legal value" of lst +itr--; // itr is now pointing at 500; +itr2 = itr--; // itr is now pointing at 400, itr2 is still pointing at 500 +itr3 = --itr; // itr is now pointing at 300, itr3 is also pointing at 300 +``` + +```cpp +// dangerous: decrementing the begin iterator is "undefined behavior" +// (similarly, incrementing the end iterator is also undefined) +// it may seem to work, but break later on this machine or on another machine! +itr = lst.begin(); +itr--; // dangerous! +itr++; +assert (*itr == 100); // might seem ok... but rewrite the code to avoid this! +``` + +## 9.8 A New Datatype: The list Standard Library Container Class - Lists are our second standard-library container class. (Vectors were the first.) Both lists & vectors store sequential data that can shrink or grow. @@ -265,7 +388,7 @@ int main() { } ``` -## 9.7 Erase & Iterators +## 9.9 Erase & Iterators STL lists and vectors each have a special member function called erase. In particular, given list of ints s, consider the example: @@ -293,14 +416,14 @@ p = s.erase(p); Even though the erase function has the same syntax for vectors and for list, the vector version is O(n), whereas the list version is O(1). Play this [animation](https://jidongxiao.github.io/CSCI1200-DataStructures/animations/lists/iterator/index.html) to see why. -## 9.8 Insert +## 9.10 Insert - Similarly, there is an insert function for STL lists that takes an iterator and a value and adds a link in the chain with the new value immediately before the item pointed to by the iterator. - The call returns an iterator that points to the newly added element. Variants on the basic insert function are also defined. -## 9.9 Leetcode Exercises +## 9.11 Leetcode Exercises - [Leetcode problem 27: Remove Element](https://leetcode.com/problems/remove-element/). Solution: [p27_removeelement.cpp](../../leetcode/p27_removeelement.cpp) - [Leetcode problem 58: Length of Last Word](https://leetcode.com/problems/length-of-last-word/). Solution: [p58_lengthoflastword.cpp](../../leetcode/p58_lengthoflastword.cpp)