Reading 3D Ragged Arrays from a File

Department → Students → Courses Structure

CPCS203 - Data Structures

1 What is a 3D Ragged Array?

3D Ragged Array Definition

A 3D ragged array is a three-dimensional array where:

  • Each department can have a different number of students
  • Each student can have a different number of courses

This is perfect for real-world university data!

Our Scenario: University Departments

We have 3 departments, each identified by an index:

Index Department Name Abbreviation
0 Computer Science CS
1 Information Technology IT
2 Information Systems IS
Array Structure

marks[department][student][course]

  • First index: Which department (0=CS, 1=IT, 2=IS)
  • Second index: Which student in that department
  • Third index: Which course mark for that student

2 Visualizing the 3D Ragged Array

3D Ragged Array: marks[3][?][?] - Each dimension is RAGGED!
Department 0 (CS) - 2 Students
Student 0:
85
90
78
← 3 courses
Student 1:
90
85
88
92
← 4 courses
Department 1 (IT) - 3 Students
Student 0:
75
80
← 2 courses
Student 1:
88
92
85
90
78
← 5 courses
Student 2:
70
75
80
← 3 courses
Department 2 (IS) - 2 Students
Student 0:
95
88
92
← 3 courses
Student 1:
80
85
← 2 courses
Why is it "Ragged" at TWO Levels?
  • Level 1 (Departments → Students): CS has 2 students, IT has 3 students, IS has 2 students
  • Level 2 (Students → Courses): Each student has a different number of courses (2, 3, 4, or 5)

3 File Format Overview

Our input file departments.txt has this structure:

departments.txt
3 // Number of departments
2 3 2 // Students per dept: CS=2, IT=3, IS=2
85 90 78 // CS Student 0: 3 courses
90 85 88 92 // CS Student 1: 4 courses
75 80 // IT Student 0: 2 courses
88 92 85 90 78 // IT Student 1: 5 courses
70 75 80 // IT Student 2: 3 courses
95 88 92 // IS Student 0: 3 courses
80 85 // IS Student 1: 2 courses
File Structure Explained
  • Line 1: Number of departments (3)
  • Line 2: Number of students in EACH department (2 3 2 means CS=2, IT=3, IS=2)
  • Remaining lines: One line per student with their course marks (variable length!)
How Many Lines Total?

2 (header lines) + 2 (CS students) + 3 (IT students) + 2 (IS students) = 9 lines

4 Reading Algorithm: Step by Step

Step 1: Read Number of Departments

Read line 1 → numDepartments = 3

Step 2: Read Students Per Department

Read line 2 → "2 3 2"

Split and convert → studentsPerDept = {2, 3, 2}

Step 3: Create the 3D Ragged Array

int[][][] marks = new int[numDepartments][][];

This creates: [null, null, null] - just 3 empty slots for departments

Step 4: For Each Department (Outer Loop)

Create a 2D array for students:

marks[d] = new int[studentsPerDept[d]][];

For d=0 (CS): marks[0] = new int[2][]; → creates space for 2 students

For d=1 (IT): marks[1] = new int[3][]; → creates space for 3 students

For d=2 (IS): marks[2] = new int[2][]; → creates space for 2 students

Step 5: For Each Student (Inner Loop)
  • Read the entire line as a string
  • Split on whitespace using split("\\s+")
  • Convert each token to int
  • Assign to marks[d][s]

5 Download Files

Download both files to run the example. Place them in the same folder!

How to Run
  1. Download both files to the same folder
  2. Open a terminal/command prompt in that folder
  3. Compile: javac Ragged3DReader.java
  4. Run: java Ragged3DReader

6 Complete Java Code

Ragged3DReader.java
 1// Ragged3DReader.java
 2import java.io.File;
 3import java.io.FileNotFoundException;
 4import java.util.Scanner;
 5
 6public class Ragged3DReader {
 7    public static void main(String[] args) {
 8        // Department names for display (index 0=CS, 1=IT, 2=IS)
 9        String[] deptNames = {"CS", "IT", "IS"};
10
11        try {
12            // Create Scanner to read from file
13            Scanner fileReader = new Scanner(new File("departments.txt"));
14
15            // ============ STEP 1: Read number of departments ============
16            int numDepartments = Integer.parseInt(fileReader.nextLine().trim());
17
18            // ============ STEP 2: Read students per department ============
19            String studentsLine = fileReader.nextLine().trim();
20            String[] studentTokens = studentsLine.split("\\s+");
21
22            // Convert to int array: studentsPerDept[d] = number of students in dept d
23            int[] studentsPerDept = new int[numDepartments];
24            for (int d = 0; d < numDepartments; d++) {
25                studentsPerDept[d] = Integer.parseInt(studentTokens[d]);
26            }
27
28            // ============ STEP 3: Create 3D ragged array ============
29            // Only first dimension specified!
30            int[][][] marks = new int[numDepartments][][];
31
32            // ============ STEP 4 & 5: Read marks for each department and student ============
33            for (int d = 0; d < numDepartments; d++) {
34                // Create 2D array for this department's students
35                marks[d] = new int[studentsPerDept[d]][];
36
37                // For each student in this department
38                for (int s = 0; s < studentsPerDept[d]; s++) {
39                    // Read the line of course marks
40                    String line = fileReader.nextLine().trim();
41
42                    // Split by whitespace
43                    String[] tokens = line.split("\\s+");
44
45                    // Create array for this student's courses
46                    int[] courses = new int[tokens.length];
47
48                    // Convert each token to int
49                    for (int c = 0; c < tokens.length; c++) {
50                        courses[c] = Integer.parseInt(tokens[c]);
51                    }
52
53                    // Assign to the 3D array
54                    marks[d][s] = courses;
55                }
56            }
57
58            // Close the file
59            fileReader.close();
60
61            // ============ PRINT THE 3D RAGGED ARRAY ============
62            System.out.println("3D Ragged Array of Department Marks:");
63            System.out.println("====================================");
64
65            for (int d = 0; d < marks.length; d++) {
66                System.out.println("\nDepartment " + d + " (" + deptNames[d] + "):");
67
68                for (int s = 0; s < marks[d].length; s++) {
69                    System.out.print("  Student " + s + ": ");
70
71                    for (int mark : marks[d][s]) {
72                        System.out.print(mark + " ");
73                    }
74                    System.out.println("(" + marks[d][s].length + " courses)");
75                }
76            }
77
78        } catch (FileNotFoundException e) {
79            System.err.println("File not found: " + e.getMessage());
80        }
81    }
82}

7 Code Explanation - Line by Line

Let's go through every line of the code so you understand exactly how to write it yourself!

Part 1: Setup and Department Names (Lines 1-13)

Lines 2-4: Import Statements

Same as 2D version - we need File, FileNotFoundException, and Scanner.

Line 9: String[] deptNames = {"CS", "IT", "IS"};

What it does: Creates an array to map index numbers to department names.

Why we need it: The file uses indices (0, 1, 2), but we want to display meaningful names.

deptNames[0] = "CS"
deptNames[1] = "IT"
deptNames[2] = "IS"
Line 13: Scanner fileReader = new Scanner(new File("departments.txt"));

What it does: Opens the file "departments.txt" for reading.

Remember: The file must be in the same folder as the Java file!

Part 2: Reading the Header Lines (Lines 15-26)

Line 16: int numDepartments = Integer.parseInt(fileReader.nextLine().trim());

What it does: Reads line 1 of the file and converts it to an integer.

Step by step:

  1. fileReader.nextLine() → reads "3"
  2. .trim() → removes any extra spaces
  3. Integer.parseInt() → converts to integer 3
After this line: numDepartments = 3
Lines 19-20: Reading Students Per Department

String studentsLine = fileReader.nextLine().trim();

String[] studentTokens = studentsLine.split("\\s+");

What it does:

  1. Line 19: Reads "2 3 2" from the file
  2. Line 20: Splits by whitespace → {"2", "3", "2"}
studentTokens[0] = "2" (CS has 2 students)
studentTokens[1] = "3" (IT has 3 students)
studentTokens[2] = "2" (IS has 2 students)
Lines 23-26: Converting to Integer Array

int[] studentsPerDept = new int[numDepartments];

for (int d = 0; d < numDepartments; d++) {

    studentsPerDept[d] = Integer.parseInt(studentTokens[d]);

}

What it does: Converts string tokens to integers.

After this loop:
studentsPerDept = {2, 3, 2}

Part 3: Creating the 3D Ragged Array (Line 30)

Line 30: int[][][] marks = new int[numDepartments][][];

What it does: Creates a 3D array with ONLY the first dimension specified!

Notice: [][] are empty - we don't know students or courses yet!

Memory visualization:
marks[0] = null (will hold CS students)
marks[1] = null (will hold IT students)
marks[2] = null (will hold IS students)

Part 4: Outer Loop - For Each Department (Lines 33-56)

Line 33: for (int d = 0; d < numDepartments; d++) {

What it does: Loops through each department (d = 0, 1, 2).

Variable naming: d for "department"

Line 35: marks[d] = new int[studentsPerDept[d]][];

What it does: Creates a 2D array for this department's students.

This is KEY! Each department gets a different number of student slots:

When d=0 (CS): marks[0] = new int[2][]; → 2 student slots
When d=1 (IT): marks[1] = new int[3][]; → 3 student slots
When d=2 (IS): marks[2] = new int[2][]; → 2 student slots

Note: The [] at the end is still empty - each student's courses will vary!

Part 5: Inner Loop - For Each Student (Lines 38-55)

Line 38: for (int s = 0; s < studentsPerDept[d]; s++) {

What it does: Loops through each student in department d.

Variable naming: s for "student"

Notice: The loop limit is studentsPerDept[d] - different for each department!

For CS (d=0): loops s = 0, 1 (2 students)
For IT (d=1): loops s = 0, 1, 2 (3 students)
For IS (d=2): loops s = 0, 1 (2 students)
Line 40: String line = fileReader.nextLine().trim();

What it does: Reads the next line from the file (one student's marks).

Example (first iteration d=0, s=0):
Reads: "85 90 78" (CS Student 0's marks)
Line 43: String[] tokens = line.split("\\s+");

What it does: Splits the line by whitespace.

Example:
Input: "85 90 78"
Result: tokens = {"85", "90", "78"}
tokens.length = 3 (this student has 3 courses)
Line 46: int[] courses = new int[tokens.length];

What it does: Creates a 1D array with the EXACT number of courses for this student.

Why tokens.length? The number of tokens tells us how many courses!

Different students, different sizes:
CS Student 0: tokens.length = 3courses = new int[3]
CS Student 1: tokens.length = 4courses = new int[4]
IT Student 1: tokens.length = 5courses = new int[5]
Lines 49-51: Converting Tokens to Integers

for (int c = 0; c < tokens.length; c++) {

    courses[c] = Integer.parseInt(tokens[c]);

}

Variable naming: c for "course"

What it does: Converts each string mark to an integer.

Example:
tokens[0] = "85"courses[0] = 85
tokens[1] = "90"courses[1] = 90
tokens[2] = "78"courses[2] = 78
Line 54: marks[d][s] = courses;

What it does: Assigns the courses array to the correct position in our 3D array.

This is the FINAL assignment!

Example (d=0, s=0):
marks[0][0] = {85, 90, 78}

Meaning: Department 0 (CS), Student 0, has marks 85, 90, 78

Part 6: Printing the 3D Array (Lines 61-76)

Line 65: for (int d = 0; d < marks.length; d++) {

What it does: Outer loop through departments.

marks.length = 3 (number of departments)

Line 66: System.out.println("\nDepartment " + d + " (" + deptNames[d] + "):");

What it does: Prints department header with name.

Example output: Department 0 (CS):

Line 68: for (int s = 0; s < marks[d].length; s++) {

What it does: Middle loop through students in department d.

marks[d].length = number of students in that department (varies!)

Line 71: for (int mark : marks[d][s]) {

What it does: Inner loop through courses for student s.

Enhanced for-loop: Automatically handles different course counts!

marks[d][s] = the 1D array of marks for this student

Line 74: System.out.println("(" + marks[d][s].length + " courses)");

What it does: Prints how many courses each student has.

marks[d][s].length = number of courses for this specific student

Complete Execution Trace

Step-by-Step with departments.txt
Step Action Result
1 Read "3" numDepartments = 3
2 Read "2 3 2" studentsPerDept = {2, 3, 2}
3 Create 3D array marks = [null, null, null]
4 d=0: Create CS array marks[0] = [null, null]
5 d=0,s=0: Read "85 90 78" marks[0][0] = {85, 90, 78}
6 d=0,s=1: Read "90 85 88 92" marks[0][1] = {90, 85, 88, 92}
7 d=1: Create IT array marks[1] = [null, null, null]
8 d=1,s=0: Read "75 80" marks[1][0] = {75, 80}
9 d=1,s=1: Read "88 92 85 90 78" marks[1][1] = {88,92,85,90,78}
10 d=1,s=2: Read "70 75 80" marks[1][2] = {70, 75, 80}
11 d=2: Create IS array marks[2] = [null, null]
12 d=2,s=0: Read "95 88 92" marks[2][0] = {95, 88, 92}
13 d=2,s=1: Read "80 85" marks[2][1] = {80, 85}

8 Expected Output

Console Output
3D Ragged Array of Department Marks:
====================================

Department 0 (CS):
  Student 0: 85 90 78 (3 courses)
  Student 1: 90 85 88 92 (4 courses)

Department 1 (IT):
  Student 0: 75 80 (2 courses)
  Student 1: 88 92 85 90 78 (5 courses)
  Student 2: 70 75 80 (3 courses)

Department 2 (IS):
  Student 0: 95 88 92 (3 courses)
  Student 1: 80 85 (2 courses)
Success!

Each department has a different number of students, and each student has a different number of courses. No wasted memory - every array is exactly the size it needs to be!

9 Key Takeaways

Summary - 3D Ragged Array
  • Declaration: int[][][] marks = new int[numDepts][][]; - only first dimension!
  • Create 2D for each department: marks[d] = new int[studentsPerDept[d]][];
  • Create 1D for each student: Let split() determine the size
  • Assign: marks[d][s] = courses;
Access Pattern

marks[department][student][course]

Example: marks[1][2][0] = IT department, Student 2, Course 0 = 70

Comparing 2D vs 3D Ragged Arrays
Feature 2D Ragged 3D Ragged
Declaration int[n][] int[n][][]
Loops needed 1 (students) 2 (departments + students)
Header lines 1 (count) 2 (count + sizes)