0
Task: Implement a function in standard C that constructs a jagged array J from a linear array W. You must adhere to the following specifications and constraints:

    Input: The function takes a single input, the array W. You can assume that global variables A, B, L, C, and NUM_PARAMS are already defined and accessible. 

    Output: The function returns J, a jagged array consisting of L+1 matrices of varying dimensions, as described below:
        V_1: A matrix of dimensions A x B, filled with the first A*B elements from W, arranged in row-major order.
        V_2 to V_L: Each is a matrix of size B x B, filled sequentially from W with B^2 elements, also in row-major order.
        V_{L+1}: A matrix of dimensions B x C, filled with the last B*C elements from W, in row-major order.

    Constraints:
        You may not use dynamic memory allocation.
        You may not use sparse arrays or maximum expected values.

    Example:
    If A = 4, B = 2, C = 3, L = 5, and W consists of integers from 1 to 30, then the resulting jagged array J would be structured as follows:
    J = [V_1, V_2, V_3, V_4, V_5, V_6], where 
J = [
  [[1, 2], [3, 4], [5, 6], [7, 8]]      // V_1 is a 4x2 matrix 
  [[9, 10], [11, 12]],                  // V_2 is a 2x2 matrix
  [[13, 14], [15, 16]],                 // V_3 is a 2x2 matrix
  [[17, 18], [19, 20]],                 // V_4 is a 2x2 matrix
  [[21, 22], [23, 24]],                 // V_5 is a 2x2 matrix
  [[25, 26, 27], [28, 29, 30]]          // V_6 is a 2x3 matrix
]

    Hint: The size of W is determined by the formula for NUM_PARAMS, which is NUM_PARAMS = A*B + (L-1)B^2 + BC.

The following is my attempt after pieces a bunch of different things together I found online. I will be honest, I do not completely understand every step very well and am just a beginner. The problem seems pretty easy to solve on paper, but I am struggling with the array of pointers aspect. My solution is almost correct, and I cant seem to find my mistake. Additionally, if I am doing very bad practice or programming principles, I would appreciate these to be addressed.

#include <stdio.h>

// Define constants globally
#define A 4
#define B 2
#define C 3
#define L 5
#define NUM_PARAMS (A * B + (L - 1) * B * B + B * C)

// Example linear array W
int W[NUM_PARAMS] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};

// Function to construct the jagged array J from W
void constructJaggedArray(int **J) {
    int currentIndex = 0;
    J[0] = &W[currentIndex];
    currentIndex += A * B;

    for (int i = 1; i < L; ++i) {
        J[i] = &W[currentIndex];
        currentIndex += B * B;
    }

    J[L] = &W[currentIndex];
    currentIndex += B * B;
    J[L+1] = &W[currentIndex];
}

void printJaggedArray(int **J) {
    // Print V_1
    printf("V_1:\n");
    for (int i = 0; i < A; i++) {
        for (int j = 0; j < B; j++) {
            printf("%d ", J[0][i * B + j]);
        }
        printf("\n");
    }

    // Print V_2 to V_L
    for (int k = 1; k <= L; k++) {
        printf("V_%d:\n", k + 1);
        for (int i = 0; i < B; i++) {
            for (int j = 0; j < B; j++) {
                printf("%d ", J[k][i * B + j]);
            }
            printf("\n");
        }
    }

    // Print V_{L+1}
    printf("V_%d:\n", L + 2);
    for (int i = 0; i < B; i++) {
        for (int j = 0; j < C; j++) {
            printf("%d ", J[L+1][i * C + j]);
        }
        printf("\n");
    }
}

int main() {
    int *J[L+1]; // Array of pointers to represent the jagged array
    constructJaggedArray(J);
    printJaggedArray(J);
    return 0;
}

OUTPUT (GCC):

V_1:                                                                                                                                                                                1 2 
3 4
5 6
7 8
V_2:
9 10
11 12
V_3:
13 14
15 16
V_4:
17 18
19 20
V_5:
21 22
23 24
V_6:
25 26
27 28
V_7:
29 30 0
0 -1856930224 32758
5
  • 2
    What makes you think your solution is "almost correct"? What "mistake" are you looking for? In other words, what behavior are you seeing and how does it differ from what you expect? Commented Jun 19, 2024 at 4:34
  • 1
    Welcome to sO. I agree to previous comment that you need to tell us what your actual question is. What is wrong with the program? BTW: J[L+1] = &W[currentIndex]; That is illegal. J can only hold elements 0..L Commented Jun 19, 2024 at 6:44
  • You seem to confuse the index values from the question (1..L+1) with the array index in your code (0..L). This for (int k = 1; k <= L; k++) should be for (int k = 1; k < L; k++) And also the last part of the print function is off by 1 in the same way Commented Jun 19, 2024 at 6:46
  • How can the program know the size of each array in the jagged 2D array? Commented Jun 19, 2024 at 9:51
  • @Gerhardh , I took into account your suggestions and posted a solution. Thanks! Commented Jun 19, 2024 at 16:01

2 Answers 2

0

You have the good idea about how to solve this exercise, but you make multiple mistakes

First of all, you have a off-by-one error while printing : with L=5 you shouldn't be printing up to V_7.

> diff old.c test.c
40c40
<     for (int k = 1; k <= L; k++) {
---
>     for (int k = 1; k <= L-1; k++) {
51c51
<     printf("V_%d:\n", L + 2);
---
>     printf("V_%d:\n", L + 1);
54c54
<             printf("%d ", J[L+1][i * C + j]);
---
>             printf("%d ", J[L][i * C + j]);

Then, J is a list of matrices (the first number is J[0][0][0]) and not (J[0][0]) as you are computing.

-- pseudo code

J[0][0][0] = (J[0]) [0] [0]
           =  V_1   [0] [0]
           = (V_1   [0])[0]
           = { 1, 2 }   [0]
           = 1

Therefore, J must be of type int **J[] instead of int *J[]. You will also have to reconsider the size of J if not J entirely.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I posted my solution after your input.
0

I took into account some of the comments and the following is a working version. If there is anything I am doing that is still "illegal" or unsafe, do let me know:

Edit: I do now realize that this solution is probably "cheating" in the sense that I am not actually storing the matrices into the array, rather I am pointing to the correct range and then via the print statements, I "form" the matrix. The correct solution likely requires the array to actually consist of the matrices of proper dimensions, but I cant really think of how to do this.

#include <stdio.h>

// Define constants globally
#define A 4
#define B 2
#define C 3
#define L 5
#define NUM_PARAMS (A * B + (L - 1) * B * B + B * C)

// Example linear array W
int W[NUM_PARAMS] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};

// Function to construct the jagged array J from W
void constructJaggedArray(int ***J) {
    int currentIndex = 0;   // Start at the beginning of W
    
    // Construct V1 (A x B matrix)    
    J[0] = (int **) &W[currentIndex];       // Point to the first element of W for V1
    currentIndex += A * B;      // Move index past the elements used for V1

    // Construct V2 to VL (B x B matrices)          
    for (int i = 1; i < L; ++i) {   
        J[i] = (int **) &W[currentIndex];   // Point to the current start index for Vi
        currentIndex += B * B;  // Move index past the elements used for Vi
    }

    // Construct V(L+1) (B x C matrix)
    J[L] = (int **) &W[currentIndex];   // Point to the current start index for V(L+1)
    // currentIndex is not incremented here as we are at the end of W
}

void printJaggedArray(int ***J) {
    // Print V_1
    printf("V_1:\n");
    for (int i = 0; i < A; i++) {
        for (int j = 0; j < B; j++) {
            printf("%d ", ((int *)J[0])[i * B + j]);
        }
        printf("\n");
    }

    // Print V_2 to V_L
    for (int k = 1; k < L; k++) {
        printf("V_%d:\n", k + 1);
        for (int i = 0; i < B; i++) {
            for (int j = 0; j < B; j++) {
                printf("%d ", ((int *)J[k])[i * B + j]);
            }
            printf("\n");
        }
    }

    // Print V_{L+1}
    printf("V_%d:\n", L + 1);
    for (int i = 0; i < B; i++) {
        for (int j = 0; j < C; j++) {
            printf("%d ", ((int *)J[L])[i * C + j]);
        }
        printf("\n");
    }
}

int main() {
    int **J[L+1];   // Array of pointers to int to represent pointers to each matrix
    constructJaggedArray((int ***)J);   // Call function to build jagged array structure
    printJaggedArray((int ***)J);
    return 0;
}

1 Comment

int **J[L+1]; Why not int *J[L+1];? You need to cast every time you access J because you have incorrect levels of indirection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.