Unit 8 | Lesson 8.1 | Lesson 8.2 | ASCII image | Homework |
8.2 Lesson
By David, Torin, Josh, Nandan
- Traversing 2D Arrays
- How can you traverse a 1D array?
- How can you traverse 2D arrays?
- Column Major Order instead of Row Major Order
- Algorithms
- Binary Search
- Sorting a 2D Array
- Enhanced For-Each Loop for 2D Arrays
- Algorithms involving traversing a 2D Array
- 2D Array Trivia Quiz
Traversing 2D Arrays
When traversing/looping through a 1D array, only one loop is required to access all elements within the array. For 2D arrays, we need to loop within the loop, which would be known as a for loop.
Java loop structure:
for (first execution; condition; executed after every loop) {
// Code that provides an action
}
An example using this structure would be something like:
```Java
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
0
1
2
3
4
5
6
7
8
9
Since the base is at 0, this code will print: 1 2 3 4 5 6 7 8 9
How can you traverse a 1D array?
Let’s create an array and name it Array1.
int[] Array1 = {1, 2, 3};
for (int i = 0; i < Array1.length; i++) {
System.out.println(Array1[i]);
}
1
2
3
In this code segment, we set our variable i to 0. Then we write a condition where if i is less than Array1.length, it prints Array1[i]. Then we add 1 to i.
How can you traverse 2D arrays?
Let’s use the same variable for this example, Array1.
This creates an array that contains 2 rows and 3 columns.
int[][] Array1 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int i = 0; i < Array1.length; i++) {
// This makes the variable i equal to 0, then the condition would be when i is less than the Array1 length,
// then it will loop to the next number, then add 1 to i.
for (int j = 0; j < Array1[i].length; j++) {
System.out.println(Array1[i][j]);
}
}
1
2
3
4
5
6
7
8
9
This sets j equal to 0. Then the next statement says while j is less than whatever the array length is within Array1 at Array1[i], it will display the value of Array1[i][j], then it will add 1 to j.
Without the loop, the code will look like this:
System.out.println(Array1[0][0]); // 1
System.out.println(Array1[0][1]); // 2
System.out.println(Array1[0][2]); // 3
System.out.println(Array1[1][0]); // 4
System.out.println(Array1[1][1]); // 5
System.out.println(Array1[1][2]); // 6
System.out.println(Array1[2][0]); // 7
System.out.println(Array1[2][1]); // 8
System.out.println(Array1[2][2]); // 9
This displays how the rows loop through the length of the array.
public class Main {
public static void main(String[] args) {
int[][] Array1 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int i = 0; i < Array1.length; i++) {
for (int j = 0; j < Array1[i].length; j++) {
System.out.println(Array1[i][j] + " (traversing to next row " + i + ")");
}
}
}
}
Main.main(null);
1 (traversing to next row 0)
2 (traversing to next row 0)
3 (traversing to next row 0)
4 (traversing to next row 1)
5 (traversing to next row 1)
6 (traversing to next row 1)
7 (traversing to next row 2)
8 (traversing to next row 2)
9 (traversing to next row 2)
Popcorn Hack
An array called find is shown below. In this popcorn hack, I want you to loop through the numbers until you get to the number that doesn’t belong (55). Then print that number along with which row and column it is located in.
public class Main {
public static void main(String[] args) {
int find[][] = {
{10, 20, 30},
{40, 55, 60},
{70, 80, 90},
};
// Write your code here
}
}
Main.main(null);
Column Major Order instead of Row Major Order
-
Definition: Column Major Order involves processing the elements of a 2D array by columns before rows.
- Switching Loops:
- Outer Loop: Iterate through columns instead of rows.
- Inner Loop: Iterate through rows instead of columns.
- Implementation Changes:
- Replace
Array1[i].length
withArray1[0].length
to focus on the number of columns.
- Replace
- Iteration Process:
- For each column (indexed by
j
), process all rows (indexed byi
). - Print the value at the current column for each row.
- After processing all rows for the current column, increment the column index
j
to move to the next column.
- For each column (indexed by
-
Example: In an array like
{1, 2, 3}
, the inner loop runs for the length of the row (number of columns). - Overall Effect: By reversing the loop structure, columns are processed before rows, achieving a Column Major Order traversal.
public class Main {
public static void main(String[] args) {
int[][] Array1 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int j = 0; j < Array1[0].length; j++) {
System.out.println("Column " + (j + 1));
for (int i = 0; i < Array1.length; i++) {
System.out.println(Array1[i][j]);
}
}
}
}
Main.main(null);
This displays each column and what is within each column.
Algorithms
Linear search is a very easy and sequential searching algorithm that allows us to find certain elements within the array or not in the array. This is done by traversing through each element.
Here is an example of a linear search within a 2D array:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[][] array = {
{10, 15, 20},
{25, 30, 35},
{40, 22, 50}
};
int target = 22; // The number we want to search for
int[] result = linearSearch(array, target);
if (result[0] != -1) {
System.out.println("Element found at index: " + Arrays.toString(result));
} else {
System.out.println("Element not found.");
}
}
static int[] linearSearch(int[][] arr, int target) {
for (int i = 0; i < arr.length; i++) { // Loop through rows
for (int j = 0; j < arr[i].length; j++) { // Loop through columns
if (arr[i][j] == target) { // Check if the current element matches the target
return new int[] {i, j}; // Return the row and column index
}
}
}
return new int[] {-1, -1}; // Return -1 if the target is not found
}
}
Main.main(null);
Element found at index: [2, 1]
Checks each element in the array sequentially until the target value is found or the end of the array is reached. Can be implemented on both sorted and unsorted arrays.
Binary Search
Divide the sorted array in half repeatedly to locate the target value. It starts by comparing the target value to the middle element of the array. If the target is equal to the middle element, the search is complete. If the target is less than the middle element, the search continues in the lower half; if greater, it continues in the upper half. This process is repeated until the target is found or the search space is exhausted.
public class Main {
public static void main(String[] args) {
int[][] array = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
int target = 10;
int[] result = binarySearch2D(array, target);
if (result[0] != -1) {
System.out.println("Element found at: Row " + result[0] + ", Column " + result[1]);
} else {
System.out.println("Element not found.");
}
}
public static int[] binarySearch2D(int[][] array, int target) {
int rows = array.length;
if (rows == 0) return new int[] {-1, -1};
int cols = array[0].length;
int left = 0;
int right = rows * cols - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int midValue = array[mid / cols][mid % cols];
if (midValue == target) {
return new int[] {mid / cols, mid % cols}; // Return the row and column index
}
if (midValue < target) {
left = mid + 1; // Move to the right half
} else {
right = mid - 1; // Move to the left half
}
}
return new int[] {-1, -1}; // Target not found
}
}
Main.main(null);
Element found at: Row 2, Column 1
Popcorn Hack:
Create your own 2D array and use either binary search or linear search. (maybe both 😏 )
public class Main {
public static void main(String[] args) {
int[][] array = {
}
}
}
Main.main(null);
Sorting a 2D Array
Sorting a 2D array can be approached in two ways:
Row-wise Sorting: Each row is sorted independently, similar to sorting a 1D array.
Global Sorting: Flatten the 2D array into a 1D array, sort it, and then reshape it back into the 2D form.
public class Main {
public static void main(String[] args) {
int[][] array = {
{9, 3, 1},
{4, 6, 5},
{7, 2, 8}
};
for (int i = 0; i < array.length; i++) {
Arrays.sort(array[i]); // Sort each row individually
}
// Print the sorted 2D array
for (int[] row : array) {
System.out.println(Arrays.toString(row));
}
}
}
Main.main(null);
[1, 3, 9]
[4, 5, 6]
[2, 7, 8]
Class Declaration:
-
The code is contained within a public class named
Main
. - Main Method:
- The
main
method is the entry point of the program where execution begins.
- The
- 2D Array Initialization:
- A 2D array named
array
is initialized with three rows, each containing three integers. - The initial array looks like this:
{ {9, 3, 1}, {4, 6, 5}, {7, 2, 8} }
- A 2D array named
- Sorting Each Row:
- A
for
loop iterates through each row of the 2D array using the indexi
. - The
Arrays.sort(array[i])
method is called for each row:- This method sorts the elements of the current row in ascending order.
- After sorting, the array transforms as follows:
- First row:
{1, 3, 9}
- Second row:
{4, 5, 6}
- Third row:
{2, 7, 8}
- First row:
- A
- Printing the Sorted Array:
- A
for-each
loop iterates through each row of the sorted array. System.out.println(Arrays.toString(row))
prints each row as a string representation:- Each sorted row is displayed on a new line, resulting in the following output:
[1, 3, 9] [4, 5, 6] [2, 7, 8]
- Each sorted row is displayed on a new line, resulting in the following output:
- A
- Program Execution:
- The line
Main.main(null);
invokes themain
method, which executes the code above.
- The line
Global Sorting:
Questions for Further Discussion
- What are some scenarios where global sorting might be more beneficial than row-wise or column-wise sorting?
- How does the complexity of flattening, sorting, and reshaping compare to other data manipulation techniques?
Steps for Global sorting:
Flattening the 2D array, sorting it, and then reshaping it.
public class Main {
public static void main(String[] args) {
int[][] array = {
{9, 3, 1},
{4, 6, 5},
{7, 2, 8}
};
int rows = array.length;
int cols = array[0].length;
int[] flatArray = new int[rows * cols];
// Flatten the 2D array into a 1D array
int index = 0;
for (int[] row : array) {
for (int num : row) {
flatArray[index++] = num;
}
}
// Sort the 1D array
Arrays.sort(flatArray);
// Reshape the 1D array back into a 2D array
index = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
array[i][j] = flatArray[index++];
}
}
// Print the globally sorted 2D array
for (int[] row : array) {
System.out.println(Arrays.toString(row));
}
}
}
Main.main(null);
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Steps for Global Sorting
- Initialize the 2D Array:
- Define the 2D array with specific dimensions and values.
- Flatten the Array:
- Create a new 1D array that can hold all the elements from the 2D array.
- Use nested loops to copy each element from the 2D array to the 1D array.
- Sort the 1D Array:
- Utilize a sorting method to arrange the elements in the 1D array in the desired order.
- Reshape into 2D Array:
- Reassign the sorted values back into the original 2D array using nested loops.
- Print the Sorted 2D Array:
- Display the final sorted 2D array to visualize the results.
Benefits of Global Sorting
- Unified Order: Provides a single sorted view of all elements, regardless of their original positions.
- Simplified Processing: Easier to apply algorithms that require a sorted list of elements.
Popcorn Hack:
Write a code that performs global sorting on your own 2D array.
public class PopcornHack {
public static void main(String[] args) {
// Step 1: Create a 2D array
int[][] array = {
{ /* Fill in your array data here */ },
{ /* More data */ },
{ /* More data */ }
};
// Step 2: Define your target number
int target = /* Choose a number to search for */;
// Step 3: Call the search method (choose either linear or binary search)
int[] result = /* Call your chosen search method here */;
// Step 4: Output the result
if (result[0] != -1) {
System.out.println("Element found at: Row " + result[0] + ", Column " + result[1]);
} else {
System.out.println("Element not found.");
}
}
// Option 1: Linear Search (Copy and paste the linear search method here)
// Option 2: Binary Search (Copy and paste the binary search method here)
}
Enhanced For-Each Loop for 2D Arrays
- 2D arrays are arrays that contain other arrays.
- You can use a nested enhanced for-each loop to iterate through all the elements in a 2D array:
- The outer loop iterates over each inner array (or row).
- The inner loop goes through all the values within that specific inner array.
- For example, with a 2D array of type
String
:- The variable type for the outer loop should match the type of the inner arrays, which is
String[]
. - Ensure that the variable types in the for-each loops align with the types of the elements in the array.
- The variable type for the outer loop should match the type of the inner arrays, which is
- Enhanced for-each loops simplify code by eliminating the need for manual index management and square brackets.
- These loops are most suitable when you do not plan to modify the original values in an array of primitive types:
- The loop variable (e.g.,
fruit
in the inner loop) will not change the values stored in the array.
- The loop variable (e.g.,
- Here’s an example code segment that demonstrates how to use enhanced for-each loops with a 2D array:
public class Main {
public static void main(String[] args) {
// Define a 2D array of strings
String[][] fruits = {
{"Apple", "Banana", "Cherry"},
{"Date", "Fig", "Grape"},
{"Honeydew", "Kiwi", "Lemon"}
};
// Use enhanced for-each loops to iterate through the 2D array
for (String[] row : fruits) { // Iterate through each inner array (row)
for (String fruit : row) { // Iterate through each element in the row
System.out.print(fruit + " "); // Print the fruit name
}
System.out.println(); // Print a new line after each row
}
}
}
Main.main(null);
Apple Banana Cherry
Date Fig Grape
Honeydew Kiwi Lemon
Algorithms involving traversing a 2D Array
In the APCSA AP exam, you may be asked to write an algorithm for a 2D array based on a given scenario. College Board will present a problem, and your task will be to develop an algorithm that addresses it.
Here’s an example from the 2023 College Board APCSA exam:
The question required students to write the countIncreasingCols method. This method counts how many columns in the grid (a 2D array filled with random numbers) are in increasing order.
public class Main {
public static void main(String[] args) {
System.out.print("columns increasing = " + countIncreasingCols());
}
}
public int countIncreasingCols() {
int count = 0;
int[][] grid = {
{1, 2, 3,4,5},
{6, 7, 8,32,10},
{11, 12, 23,14,15},
{16, 17, 18,19,5}
};
for (int j = 0; j < grid[0].length; j++) { // Loop through each column
boolean isIncreasing = true;
if (grid.length > 1) { // Ensure there is more than one row
for (int i = 1; i < grid.length; i++) { // Loop through each row
if (grid[i][j] <= grid[i - 1][j]) { // Check if the current element is less than or equal to the previous one
isIncreasing = false; // Set isIncreasing to false and exit the loop
break;
}
}
if (isIncreasing) { // If the column is increasing, increase the count
count++;
}
}
else if (grid.length == 1) { // If there is only one row, count it as increasing
count++;
}
else { // If there are no rows, exit the loop
break;
}
}
return count;
}
Main.main(null);
columns increasing = 2