c++matrix

C++ Find the sum of elements between minimum and maximum element of matrix


So, My program works as it should, but only if minimum and maximum element are in opposite corners. So my question is how to iterate two-dimensional array from one certain element to another(and perhaps get rid of some nested loops). Shall I convert this array to one-dimensional?

Here's the correct work of the code:

Here's correct work of the code

And here's when something went wrong. The elements {0}{1} and {1}{1} got lost.

enter image description here

And here's the shortened varian of the code:

#include <iostream>

using namespace std;

void matrix_count(int a[5][5],int min, int max, int min_i, int min_j, int max_i, int max_j) {
    int suma = 0;
    int counter = 0;
    if (min_i <= max_i && min_j <= max_j) { 
        for (int i = 0; i < 5; i++) {       //iterating all matrix
            for (int j = 0; j < 5; j++) {
                if (a[i][j] == min) {       //start a new cycle when find min
                    for (int i = min_i; i < 5; i++) {
                        for (int j = min_j; j < 5; j++) {
                            if (a[i][j] == max) { i = 5; break; }
                            else if (a[i][j] != min) {
                                counter++;
                                suma += a[i][j];
                                cout << a[i][j] << " ";
                            }
                        }
                    }
                }
            }
        }
    }
    else if (min_i >= max_i && min_j <= max_j) {} // min[i]<max[i] min[j]<max[j]
    else if (min_i <= max_i && min_j >= max_j) {} // min[i]<max[i] min[j]>max[j]
    else if (min_i >= max_i && min_j >= max_j) {} // min[i]>max[i] min[j]>max[j]
    cout << endl;
    cout << suma << endl;
    cout << counter << endl;
}

int main()
{
    int a[5][5] = { 
        {0,4,6,3,5},
        {7,1,5,6,2},
        {6,8,8,5,2},
        {4,1,5,2,2},
        {4,3,6,5,9} };
    int min = a[0][0];
    int max = a[0][0];
    int max_i = 0;
    int min_i = 0;
    int max_j = 0;
    int min_j = 0;

// finding the max
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (a[i][j] > max) {
                max = a[i][j];
                max_i = i;
                max_j = j;
            }
        }
    }

// finding the min
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (a[i][j] < min) {
                min = a[i][j];
                min_i = i;
                min_j = j;
            }
        }
    }

    matrix_count(a, min, max, min_i, min_j, max_i, max_j);

    return 0;
}

Solution

  • As my comment stated, one solution is to realize that the two-dimensional array has a layout of its data in contiguous memory. Thus getting the minimum, maximum, and sum become simple, since you would traverse the two-dimensional array in the same way as a one-dimensional array.

    Here is a solution using C++ algorithm functions.

    #include <algorithm>
    #include <iostream>
    #include <numeric>
    
    int main()
    {
        int a[5][5] = {
            {0,4,6,3,5},
            {7,1,5,6,2},
            {6,8,8,5,2},
            {4,1,5,2,2},
            {4,3,6,5,9} };
    
        // Get both the position of the minimum and maximum element in the array  
        auto pr = std::minmax_element(&a[0][0], &a[4][5]);
    
        // add up all elements between the min and max elements 
        int answer = std::accumulate(std::next(pr.first), pr.second, 0);
    
        // output results
        std::cout << answer;
    }
    

    Output:

    100
    

    Yes, that is the entire code.

    So what was done?

    First, we use std::minmax_element to traverse the array starting from a pointer to the first element (&a[0][0]) to one passed the last element (&a[4][5]). Note the arguments to the function -- the reason why this works is that a two-dimensional array has that contiguous layout I mentioned earlier. So it's just a matter of figuring out the starting and ending positions.

    The return value of std::minmax_element is a std::pair<int*, int*> that point to the minimum element (the first) and maximum element (the second). That is what the pr denotes.

    Once that's done, we can quickly add up the items between the minimum and maximum elements by using std::accumulate with the pointers we have from pr.

    Note that the first argument to std::accumulate is the next value after the minimum value found. That is the reason for the std::next in the first argument -- it takes us to the next value.