c++arrayspointersmatrixsubmatrix

Function to calculate average of Sum of all elements in sub-matrix



I want to make a function that take three arguments

  1. 2-D array. (int array[rows][cols])
  2. an integer. (int n)
  3. address of array[i][j].

Means my function prototype should look like this double Sub_avg(int arr[rows][cols], int n, int *arr[i][j])


Function Explanation


Sample Input


Output


  1. Is there any library function or template for this kind of calculations?
  2. My main concern is how to pass a 2D array at run-time because user is going to enter the dimensions of array.

Solution

  • Of cause usually in C++ you will use std::vector or std::array to store arrays and pass them around. But if you really need to work with plain old arrays and pointers then I'm providing next my solution of your task. Also when passing plain arrays you may use templates magic but I thought you want to have something very simple.

    I minimally modified your function interface to become enough to solve the task with plain arrays and pointers. You should pass array as int const *, because in C/C++ you can't pass int arr[rows][cols] without templates magic, also you have to pass rows and cols because function doesn't know dimensions of array, also instead of passing a pointer to sub-array you should pass sub_row and sub_col position inside array.

    Also I decided to implement Sub_avg2() function, which is very close to interface of your function, but it is more high-level and complex, because it uses templates. Also because of templates it means that your function's body should be placed only into header .h file of your library, body should be available as source at compile time. But extra bonus is that this function does extra compile time automatic work of passing array dimensions around.

    Also you can notice that I do extra out of bounds checking in my code and returning 0 in case of error.

    Try it online!

    #include <iostream>
    
    static double Sub_avg(int const * arr, int rows, int cols, int n, int sub_row, int sub_col) {
        if (!arr || rows < 0 || cols < 0 || n < 0 || sub_row < 0 || sub_col < 0 || sub_row + n > rows || sub_col + n > cols)
            return 0; // Just out of bounds checking. Return error.
        double sum = 0;
        for (size_t i = 0; i < n; ++i)
            for (size_t j = 0; j < n; ++j)
                sum += arr[(sub_row + i) * cols + sub_col + j];
        return sum / double(n * n);
    }
    
    template <int rows, int cols>
    static double Sub_avg2(int const (&arr)[rows][cols], int n, int const * sarr) {
        int sub_row = (sarr - &arr[0][0]) / cols, sub_col = (sarr - &arr[0][0]) % cols;
        if (!arr || rows < 0 || cols < 0 || n < 0 || sub_row < 0 || sub_col < 0 || sub_row + n > rows || sub_col + n > cols)
            return 0; // Just out of bounds checking. Return error.
        double sum = 0;
        for (size_t i = 0; i < n; ++i)
            for (size_t j = 0; j < n; ++j)
                sum += arr[sub_row + i][sub_col + j];
        return sum / double(n * n);
    }
    
    int main() {
        int const rows = 3, cols = 3, n = 2, sub_row = 1, sub_col = 1;
        int arr[rows][cols] = {{3, 5, 6}, {5, 8, 7}, {5, 9, 9}};
        std::cout << Sub_avg((int*)arr, rows, cols, n, sub_row, sub_col) << std::endl;
        std::cout << Sub_avg2(arr, n, &arr[sub_row][sub_col]) << std::endl;
    }
    

    Output:

    8.25
    8.25