Question 3: 2D Arrays

3a

PART A: Write the SparseArray method getValueAt. The method returns the value of the sparse array element at a given row and column in the sparse array. If the list entries contains an entry with the specified row and column, the value associated with the entry is returned. If there is no entry in entries corresponding to the specified row and column, 0 is returned. In the example above, the call sparse.getValueAt(3, 1) would return -9, and sparse.getValueAt(3, 3) would return 0.

import java.util.ArrayList;

class SparseArrayEntry {
    private int row;
    private int col;
    private int value;

    public SparseArrayEntry(int row, int col, int value) {
        this.row = row;
        this.col = col;
        this.value = value;
    }

    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }

    public int getValue() {
        return value;
    }
}

class SparseArray {
    private ArrayList<SparseArrayEntry> entries;

    public SparseArray() {
        entries = new ArrayList<>();
    }

    public void addEntry(SparseArrayEntry entry) {
        entries.add(entry);
    }

    public int getValueAt(int row, int col) {
        for (SparseArrayEntry e : entries) {
            if (e.getRow() == row && e.getCol() == col) {
                return e.getValue();
            }
        }
        return 0;
    }
}

public class Main {
    public static void main(String[] args) {
        SparseArray sparse = new SparseArray();

        // Adding some entries for testing
        sparse.addEntry(new SparseArrayEntry(1, 1, 100));
        sparse.addEntry(new SparseArrayEntry(1, 2, 200));
        sparse.addEntry(new SparseArrayEntry(1, 3, 300));
        sparse.addEntry(new SparseArrayEntry(2, 1, 400));

        // Testing the getValueAt method
        System.out.println("Value at (1, 1): " + sparse.getValueAt(1, 1)); // the output should be 100
        System.out.println("Value at (2, 2): " + sparse.getValueAt(2, 2)); // the output should be 0
        System.out.println("Value at (3, 1): " + sparse.getValueAt(3, 1)); // the output should be 0
        System.out.println("Value at (3, 3): " + sparse.getValueAt(3, 3)); // the output should be 0
    }
}

Main.main(null);

3a Explanation

The getValueAt method within my SparseArray class is crafted to retrieve the value stored at a specific position within a sparse array. I designed the method to iterate through each SparseArrayEntry in the entries list and check if the row and column indices of the entry match the provided indices. When a match is found, I ensure that the corresponding value is returned; otherwise, I make sure the method returns 0, indicating that no value exists at the specified position. To guarantee the correctness of my getValueAt method, I conducted testing within the main method of my Main class. I created test cases by adding various SparseArrayEntry objects to my SparseArray instance sparse, each representing a unique position within the sparse array along with its associated value. Then, I called the getValueAt method with different row and column indices, and I printed the returned values to the console along with expected outputs, meticulously validating the functionality of my method.

Output:

Value at (1, 1): 100
Value at (2, 2): 0
Value at (3, 1): 0
Value at (3, 3): 0

3b

PART B: Write the SparseArray method removeColumn. After removing a specified column from a sparsearray:

All entries in the list entries with column indexes matching col are removed from the list.

All entries in the list entries with column indexes greater than col are replaced by entries with column indexes that are decremented by one (moved one column to the left).

The number of columns in the sparse array is adjusted to reflect the column removed.

import java.util.ArrayList;
import java.util.Iterator;

class SparseArrayEntry {
    private int row;
    private int col;
    private int value;

    public SparseArrayEntry(int row, int col, int value) {
        this.row = row;
        this.col = col;
        this.value = value;
    }

    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }

    public int getValue() {
        return value;
    }
}

class SparseArray {
    private ArrayList<SparseArrayEntry> entries;
    private int numRows;
    private int numCols;

    public SparseArray(int numRows, int numCols) {
        entries = new ArrayList<>();
        this.numRows = numRows;
        this.numCols = numCols;
    }

    public void addEntry(SparseArrayEntry entry) {
        entries.add(entry);
    }

    public void removeColumn(int col) {
        // Iterate through entries and remove entries with specified column
        Iterator<SparseArrayEntry> iterator = entries.iterator();
        while (iterator.hasNext()) {
            SparseArrayEntry entry = iterator.next();
            if (entry.getCol() == col) {
                iterator.remove(); // Remove entry with specified column
            }
        }

        // Update numCols after removing the column
        numCols--;
    }

    public int getValueAt(int row, int col) {
        for (SparseArrayEntry e : entries) {
            if (e.getRow() == row && e.getCol() == col) {
                return e.getValue();
            }
        }
        return 0;
    }

    public int getNumRows() {


        return numRows;
    }

    public int getNumCols() {
        return numCols;
    }
}

public class Main {
    public static void main(String[] args) {
        SparseArray sparse = new SparseArray(3, 3);

        // testing the program
        sparse.addEntry(new SparseArrayEntry(1, 1, 100));
        sparse.addEntry(new SparseArrayEntry(1, 2, 200));
        sparse.addEntry(new SparseArrayEntry(2, 2, 300));
        sparse.addEntry(new SparseArrayEntry(3, 1, 400));
        sparse.addEntry(new SparseArrayEntry(3, 3, 500));

        // REMOVE COLUMN 2
        sparse.removeColumn(2);

        // Testing the getValueAt method
        System.out.println("Value at (1, 1): " + sparse.getValueAt(1, 1)); // the output should be 100
        System.out.println("Value at (1, 2): " + sparse.getValueAt(1, 2)); // the output should be 0
        System.out.println("Value at (2, 2): " + sparse.getValueAt(2, 2)); // the output should be 0
        System.out.println("Value at (3, 1): " + sparse.getValueAt(3, 1)); // the output should be 400
        System.out.println("Value at (3, 3): " + sparse.getValueAt(3, 3)); // the output should be 500

        System.out.println("# of rows: " + sparse.getNumRows()); // the output should be 3
        System.out.println("# of columns " + sparse.getNumCols()); // the output should be 2
    }
}

Main.main(null);

3b Explanation

The removeColumn method within the SparseArray class was developed by me to remove all entries in the array corresponding to a specified column. I began by initializing an iterator to traverse through the list of entries. Iterating over each entry, I checked if the column of the current entry matched the specified column to be removed. If a match was found, I removed the entry from the list using the iterator. After iterating through all entries, I decremented the numCols variable to reflect the removal of the specified column. This method was then tested within the Main class’s main method. I created a SparseArray instance, populated it with entries, and invoked the removeColumn method to remove a specific column. Subsequently, I used the getValueAt method to verify the presence or absence of entries in the modified array. Finally, I called the getNumRows and getNumCols methods to ensure that the dimensions of the array were correctly updated after column removal.

Output:

Value at (1, 1): 100
Value at (1, 2): 0
Value at (2, 2): 0
Value at (3, 1): 400
Value at (3, 3): 500
# of rows: 3
# of columns 2
package com.nighthawk.spring_portfolio.mvc.knn;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

// Add necessary Spring Boot annotations and imports
@RestController
@RequestMapping("/api/worker")
@CrossOrigin(origins = "https://rik-csa.github.io/") // Add the origin of
// @CrossOrigin(origins = "http://127.0.0.1:4100/") // Add the origin of
// your frontend
// application
public class WorkerController {

    private List<Worker> workers = new ArrayList<>(); // Initialize your worker list

    public WorkerController() {
        workers.add(new Worker("John Kim", Arrays.asList("Python", "Java"), "Chicago", true));
        workers.add(new Worker("Jane Zheng", Arrays.asList("C++", "Matlab"), "California", false));
        workers.add(new Worker("Bobby Fischer", Arrays.asList("Java", "JavaScript"), "New York", true));
        workers.add(
                new Worker("David Lee", Arrays.asList("Python", "Java", "Matlab", "JavaScript"), "San Diego", true));
        workers.add(new Worker("Alice Tang", Arrays.asList("Python", "C++", "JavaScript"), "San Diego", true));
        workers.add(new Worker("Amanda Le", Arrays.asList("Python", "Matlab", "JavaScript"), "San Diego", false));
        workers.add(new Worker("James Lo", Arrays.asList("Python", "Java", "Matlab"), "San Diego", false));
        workers.add(new Worker("Jiang Du", Arrays.asList("Java", "Matlab"), "San Diego", false));
        workers.add(new Worker("Sophia Tang", Arrays.asList("Python"), "San Diego, California", true));
        workers.add(new Worker("Alicia Ji", Arrays.asList("Python, Java"), "Cambridge, Massachusetts", true));
        workers.add(new Worker("Evan Ji", Arrays.asList("Java"), "San Diego", true));
        workers.add(new Worker("Ellen Xu", Arrays.asList("Python, Java"), "Sacramento, California", true));
        workers.add(new Worker("Joseph Youm", Arrays.asList("Javascript, HTML, Go, C#, C++"), "San Diego", true));
        workers.add(new Worker("Alex Xiao", Arrays.asList("Javascript, HTML"), "Pittsburgh, Pennsylvania", true));
        workers.add(new Worker("Amanda Yang", Arrays.asList("Python"), "Austin, Texas", true));
        workers.add(
                new Worker("Ellen Kang", Arrays.asList("Java, C++, Matlab, HTML"), "Pittsburgh, Pennsylvania", true));
        workers.add(new Worker("Brian J. Wang",
                Arrays.asList("PHP, Python, Java, C++, Matlab, C, CSS, Ruby"), "Pittsburgh, Pennsylvania", false));
        workers.add(new Worker("Amanda Wang", Arrays.asList("Java, C++, Matlab, C"), "Pittsburgh, Pennsylvania", true));


        workers.add(new Worker("Alex Yang", Arrays.asList("Python, Java, C++"), "Pittsburgh, Pennsylvania", true));
        workers.add(new Worker("Ellen Zhang", Arrays.asList("Python, Java, C++"), "Austin, Texas", false));
    }

    @GetMapping
    public ResponseEntity<List<Worker>> getWorkers() {
        return ResponseEntity.ok(workers);
    }

    @PostMapping("/search")
    public ResponseEntity<List<Worker>> searchWorkers(@RequestParam String language) {
        // Implement your search logic here
        List<Worker> foundWorkers = new ArrayList<>();
        for (Worker worker : workers) {
            if (worker.getLanguages().contains(language)) {
                foundWorkers.add(worker);
            }
        }
        return ResponseEntity.ok(foundWorkers);
    }

    @PostMapping("/filter")
    public ResponseEntity<List<Worker>> filterWorkers(@RequestBody FilterRequest filterRequest) {
        // Implement your filter logic here
        List<Worker> filteredWorkers = new ArrayList<>();
        for (Worker worker : workers) {
            if (worker.isAvailable() == filterRequest.isAvailable()
                    && worker.getCity().equalsIgnoreCase(filterRequest.getCity())) {
                filteredWorkers.add(worker);
            }
        }
        return ResponseEntity.ok(filteredWorkers);
    }
}
package com.nighthawk.spring_portfolio.mvc.knn;

// Add necessary Spring Boot annotations and imports

public class FilterRequest {

    private boolean available;
    private String city;

    // Add getters and setters
    public boolean isAvailable() {
        return available;
    }

    public void setAvailable(boolean available) {
        this.available = available;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}
package com.nighthawk.spring_portfolio.mvc.knn;

// Add necessary Spring Boot annotations and imports
public class Worker {
    private String name;
    private List<String> languages;
    private String city;
    private boolean available;

    // Add a constructor, getters, and setters
    public Worker(String name, List<String> languages, String city, boolean available) {
        this.name = name;
        this.languages = languages;
        this.city = city;
        this.available = available;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getLanguages() {
        return languages;
    }

    public void setLanguages(List<String> languages) {
        this.languages = languages;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public boolean isAvailable() {
        return available;
    }

    public void setAvailable(boolean available) {
        this.available = available;
    }
}

This Java Spring Boot controller class, WorkerController, manages HTTP requests related to a worker database. The controller provides endpoints for retrieving all workers, searching for workers by programming language, and filtering workers by availability and city. Additionally, it includes supporting classes FilterRequest and Worker to represent filter criteria and worker information, respectively. ```