Welcome to today's session on "Multidimensional Arrays and Their Traversal in C++". Multidimensional arrays are types of arrays that store arrays at each index instead of single elements. Picture it as an 'apartment building' with floors (the outer array) and apartments on each floor (the inner array). Our goal today is to strengthen your foundational knowledge of these 'apartment buildings' and how to handle them effectively in C++.
To construct a multidimensional array in C++, we use vectors inside vectors. Here's an example of a 2-dimensional array:
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 // Creating a 2D vector 6 std::vector<std::vector<int>> array = {{1, 2, 3}, 7 {4, 5, 6}, 8 {7, 8, 9}}; 9 10 // Printing the array 11 for (int i = 0; i < array.size(); i++) { 12 for (int j = 0; j < array[i].size(); j++) { 13 std::cout << array[i][j] << " "; 14 } 15 std::cout << std::endl; 16 } 17 return 0; 18}
In this example, array
is a 2-dimensional vector, just like a 3-story 'apartment building,' where every floor is an inner vector.
All indices in C++ arrays are 0-based. Let's say you want to visit an apartment on the second floor (index 1
) and bring a package to the first unit (index 0
) in this building. Here's how you can do it:
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<int>> array = {{1, 2, 3}, 6 {4, 5, 6}, 7 {7, 8, 9}}; 8 9 // Accessing an element 10 std::cout << array[1][0] << std::endl; // Outputs: 4 11 12 return 0; 13}
We visited the element 4
in the array
by its position. The number 1
inside the first square brackets refers to the second inner vector, and 0
refers to the first element of that vector.
Continuing with the apartment-building analogy, suppose the task was to replace the old locker code (the second element in the first array) with a new one. Here's how we can achieve this:
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 // Defining and initializing array 6 std::vector<std::vector<int>> array = {{1, 2, 3}, 7 {4, 5, 6}, 8 {7, 8, 9}}; 9 10 // Updating an element 11 array[0][1] = 10; 12 for (int i = 0; i < array.size(); i++) { 13 for (int j = 0; j < array[i].size(); j++) { 14 std::cout << array[i][j] << " "; 15 } 16 std::cout << std::endl; 17 } 18 return 0; 19}
C++ offers various ways to manage multidimensional arrays when using the std::vector
container:
- Finding the number of rows (size): It's like asking how many floors there are in our 'apartment building.' If we use
std::vector
, we can use thesize()
method. Additionally, we can find the number of columns (units on each floor) by using thesize()
method on the first inner vector (assuming it is a non-jagged array, i.e. all inner vectors have the same size):
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<int>> array = {{1, 2, 3}, 6 {4, 5, 6}, 7 {7, 8, 9}}; 8 9 // Finding the number of rows 10 int num_floors = array.size(); 11 std::cout << num_floors << std::endl; // Outputs: 3 12 13 // Finding the number of columns 14 int num_units = array[0].size(); 15 std::cout << num_units << std::endl; // Outputs: 3 16 17 return 0; 18}
- Adding a new row (push_back): We can add a new floor and units on that floor to our 'apartment building' using
push_back()
:
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<int>> array = {{1, 2, 3}, 6 {4, 5, 6}, 7 {7, 8, 9}}; 8 9 // Adding a new row to our array 10 array.push_back({10, 11, 12}); 11 for (const auto& floor : array) { 12 for (int unit : floor) { 13 std::cout << unit << " "; 14 } 15 std::cout << std::endl; 16 } 17 18 return 0; 19}
- Removing an element (erase): We can rely on
erase()
to help us get rid of a particular element in our array:
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<int>> array = {{1, 2, 3}, 6 {4, 5, 6}, 7 {7, 8, 9}}; 8 9 // Removing the second element of the second row 10 array[1].erase(array[1].begin() + 1); 11 for (const auto& floor : array) { 12 for (int unit : floor) { 13 std::cout << unit << " "; 14 } 15 std::cout << std::endl; 16 } 17 18 return 0; 19}
We can visit every floor (outer array) and every apartment on each floor (inner array) by using nested loops.
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<std::string>> array = {{"Apt 101", "Apt 102", "Apt 103"}, 6 {"Apt 201", "Exit Floor", "Apt 203"}, 7 {"Apt 301", "Apt 302", "Apt 303"}}; 8 9 // Loop through 2D array 10 for (const auto& floor : array) { 11 for (const auto& unit : floor) { 12 std::cout << unit << ", "; 13 } 14 std::cout << std::endl; 15 } 16 17 return 0; 18} 19 20/* 21Prints: 22Apt 101, Apt 102, Apt 103, 23Apt 201, Exit Floor, Apt 203, 24Apt 301, Apt 302, Apt 303, 25*/
Sometimes, when we visit every apartment on each floor, we might need to start visiting the next floor midway. break
helps us exit the current loop, while continue
helps us skip the current iteration and move to the next one.
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<std::string>> array = {{"Apt 101", "Apt 102", "Apt 103"}, 6 {"Apt 201", "Exit Floor", "Apt 203"}, 7 {"Apt 301", "Apt 302", "Apt 303"}}; 8 9 // Break in nested loop 10 for (const auto& floor : array) { 11 for (const auto& unit : floor) { 12 if (unit == "Exit Floor") { 13 break; 14 } 15 std::cout << unit << ", "; 16 } 17 std::cout << std::endl; 18 } 19 20 return 0; 21} 22 23/* 24Prints: 25Apt 101, Apt 102, Apt 103, 26Apt 201, 27Apt 301, Apt 302, Apt 303, 28*/
Here, as soon as 'Exit Floor' is found on a floor, the entire loop breaks, and no further units on the floor are visited. However, the other units are processed as before, as break
breaks only the nested loop.
We can also make use of continue
in a similar scenario:
C++1#include <iostream> 2#include <vector> 3 4int main() { 5 std::vector<std::vector<std::string>> array = {{"Apt 101", "Apt 102", "Apt 103"}, 6 {"Apt 201", "Exit Floor", "Apt 203"}, 7 {"Apt 301", "Apt 302", "Apt 303"}}; 8 9 // Continue in nested loop 10 for (const auto& floor : array) { 11 for (const auto& unit : floor) { 12 if (unit == "Exit Floor") { 13 continue; 14 } 15 std::cout << unit << ", "; 16 } 17 std::cout << std::endl; 18 } 19 20 return 0; 21} 22 23/* 24Prints: 25Apt 101, Apt 102, Apt 103, 26Apt 201, Apt 203, 27Apt 301, Apt 302, Apt 303, 28*/
In this case, when 'Exit Floor' is encountered, the continue
statement is executed. This skips printing 'Exit Floor' and continues with the next unit on the same floor. The loop doesn't stop entirely but skips over 'Exit Floor,' resulting in a missing apartment in the printout for the second floor.
That was exciting! We went through various operations on multidimensional arrays, starting from their creation, methods to update, and useful C++ methods. We also learned how we can visit every floor and every apartment on each floor.
Practice solidifies learning! Your new adventure awaits in our upcoming practical exercises, where you can apply these concepts on multidimensional arrays! Buckle up and have fun!