function to calculate average of Sum of all elements in sub-matrix [closed]


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

  • first argument is 2D array that represents data which is going to be processed.

  • Here n stands for n x n matrix means the dimension of square matrix whose average of all elements is required.

  • The last argument int arr[i][j] is the address of first element of sub matrix.


Sample Input

  • for example let us take 3×3 matrix,
  • enter image description here
  • I want to calculate for the sub matrix
  • List item

Output

  • then the function would return 8.25 that is (8 + 7 + 9 + 9)/4.

  1. Is there any library function or template for this kind of calculations?
  2. Is there any other way to get the solution?

Answer

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