2D arrays with variable sizes as arguments C++

Viewed 48

I was going to create a function Swap() that swaps the two maximum elements of the n times m matrix A and matrix B. But I'm having error: declaration of 'A' as multidimensional array must have bounds for all dimensions except the first

void Swap(int A[][], int B[][], int n, int m)
{
    int max_A = A[0][0];
    int max_B = B[0][0];
    int index_Ai, index_Aj, index_Bi, index_Bj;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(max_A < A[i][j])
            {
                max_A = A[i][j];
                index_Ai = i;
                index_Aj = j;
            }
        }
    }
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(max_B < B[i][j])
            {
                max_B = B[i][j];
                index_Bi = i;
                index_Bj = j;
            }
        }
    }
    int temp;
     temp = A[index_Ai][index_Aj];
     A[index_Ai][index_Aj] = B[index_Bi][index_Bj];
     B[index_Bi][index_Bj] = temp;
}

How should I deal with this problem? Or should I pass just two matrices as arguments and then find their sizes inside the funcion? Any help is appreciated.

2 Answers

Assuming that your two-dimensional arrays are "regular" C++ 2D arrays (not vectors), note that the array stores its data in contiguous memory.

Given that fact, to find the maximum element in any 2D array just requires you to know the dimensions, and then use std::max_element to get a pointer to the maximum element of each array, and call std::swap to swap the elements found.

#include <algorithm>
#include <iostream>
//...
int main()
{
    const int m = 10;
    const int n = 20;

    int A[m][n] = {0};
    int B[m][n] = {0};

    // Test
    A[4][5] = 20;
    B[3][2] = 50;
    std::cout << "Before:\n" << A[4][5] << " " << B[3][2];                  

    // Swap the maximum elements  
    std::swap(*std::max_element(&A[0][0], &A[m-1][n]), 
              *std::max_element(&B[0][0], &B[m-1][n]));

    std::cout << "\n\nAfter:\n" << A[4][5] << " " << B[3][2];                  
}

Output:

Before:
20 50

After:
50 20

There is no need to create a separate function.


If you had to create a function, then probably a template function would be what you are looking for:

#include <algorithm>
#include <iostream>
//...

template <int M, int N>
void Swap(int A[M][N], int B[M][N])
{
    std::swap(*std::max_element(&A[0][0], &A[M-1][N]), 
              *std::max_element(&B[0][0], &B[M-1][N]));
}


int main()
{
    const int m = 10;
    const int n = 20;

    int A[m][n] = {0};
    int B[m][n] = {0};

    A[4][5] = 20;
    B[3][2] = 50;
    std::cout << "Before:\n" << A[4][5] << " " << B[3][2];                  

    Swap<10,20>(A, B);

    std::cout << "\n\nAfter:\n" << A[4][5] << " " << B[3][2];                  
}

Output:

Before:
20 50

After:
50 20

Following you request here is a posssible implementation of your code using vector of vectors, aka 2D vector, with comments:

Live demo

#include <iostream>
#include <vector>
#include <exception>

//pass vectors by reference so the changes are reflected in the passed arguments
void Swap(std::vector<std::vector<int>>& A, std::vector<std::vector<int>>& B) {

    int max_A = A.at(0).at(0); //if indexing A[0][0], exception would not be thrown
    int max_B = B.at(0).at(0);
    int index_Ai, index_Aj, index_Bi, index_Bj;

    for (size_t i = 0; i < A.size(); i++) {
        for (size_t j = 0; j < A.at(0).size(); j++) {
            if (max_A < A[i][j]) { //indexing A[i][j] safe, cycle limited to vector size
                max_A = A[i][j];
                index_Ai = i;
                index_Aj = j;
            }
        }
    }
    for (size_t i = 0; i < B.size(); i++) {
        for (size_t j = 0; j < B.at(0).size(); j++) {
            if (max_B < B[i][j]) {
                max_B = B[i][j];
                index_Bi = i;
                index_Bj = j;
            }
        }
    }
    //standard library swap function
    std::swap(A.at(index_Ai).at(index_Aj), B.at(index_Bi).at(index_Bj));
}
int main() {

    std::vector<std::vector<int>> A = {{1, 2, 300}, {4, 9, 10, 56, 5, 6}};
    std::vector<std::vector<int>> B = {{10, 45, 2, 12, 20, 80}, {40, 45, 500, 60}};
    try{
        Swap(A, B);
    } catch(std::exception& e){ //if vectors accessed out of bounds throws exception
        std::cout << "ERROR: " << e.what() << std::endl; //we catch it here
        return EXIT_FAILURE;    
    }

    for (auto &v : A) { //test print A
        for (auto i : v) {
            std::cout << i << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    for (auto &v : B) { //test print B
        for (auto i : v)
        {
            std::cout << i << " ";
        }
        std::cout << std::endl;
    }
    return EXIT_SUCCESS;
}

Initial array:

1 2 300
4 9 10 56 5 6
10 45 2 12 20 80
40 45 500 60

After swap:

1 2 500
4 9 10 56 5 6 
10 45 2 12 20 80
40 45 300 60
Related