0

Im trying to set a matrix with random values between 0-50 and after make an algorithm which will not stop till rows and cols of the matrix has the same number 1 by one. Using #include and creating a function to get the max value is not working in the main for getting the max value.

Console: error: cannot convert ‘int ()[C]’ to ‘int ()[0]’ for argument ‘1’ to ‘int max_nr(int (*)[0], int, int)’ I have tried different ways for calling the funtction int max = max_nr(M,R,C);

int max = max_nr(M(*)[0],R,C);

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int max_nr(int[][0], int, int);

int main() {
    int R;
    int C;
    std::cout << "Rows:";
    cin >> R;
    cout << endl;
    std::cout << "Cols:";
    cin >> C;
    cout << endl;

    int M[R][C];

    // first we will set a aleatory number for each of the holes in the matrix
    for(int i = 0; i <= R; i++) { // will move forward one position
        for(int j = 0; j <= C; j++) {
            M[i][j] = (rand() % (50 + 1 - 1)) + 1;

        } // end cols

    } // end rows
    // show function
    for(int i = 0; i <= R; i++) { // will move forward one position
        for(int j = 0; j <= C; j++) {
            cout << M[i][j] << "||";

        } // end cols
        cout << endl;
    } // end rows
    // wors ; give aleatory number in correcto rows and cols now must stop when
    // will set all equals movin one by one in cols and cels

    for(int i = 0; i <= R; i++) {     // will move forward one position
        for(int j = 0; j <= C; j++) { // forward col=

        } // end cols
        cout << endl;
    } // end rows

    int max = max_nr(M, R, C);
    cout << max << endl;

    return 0;
}

int max_nr(int M[][0], int R, int C) {
    int i = 0, j = 0, max = M[i][j];

    for(i = 0; i <= R; i++) {
        for(j = 0; j <= C; j++) {
            max = *std::max_element(M[i], M[j]);
        }
    }

    return max;
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • 3
    This is not valid C++ code. There are no variable length arrays in C++. – Michael Kenzel Apr 04 '19 at 17:35
  • 2
    Why do you have a function taking an array of length zero? – Silvio Mayolo Apr 04 '19 at 17:36
  • 3
    To get max value we have [std::max_element](https://en.cppreference.com/w/cpp/algorithm/max_element). Also, check out `std::array` and `std::vector` as replacements for crummy old C-style arrays. – Jesper Juhl Apr 04 '19 at 17:40
  • What is `max_nr` supposed to do? What are you trying to do with `*std::max_element(M[i], M[j])` in that function? – Ted Lyngmo Apr 04 '19 at 17:45
  • I will let here the link where i saw some example of i tryed to used, maybe i took wrong the idea [link] (https://www.programiz.com/cpp-programming/examples/matrix-multiplication-function) – Vlad Constantin Podar Apr 04 '19 at 18:57
  • The code in the link looked like a mess and used old C style arrays making it necessary to have hardcoded dimensions. Don't look there too closely. :) – Ted Lyngmo Apr 04 '19 at 20:54

2 Answers2

0

You have a lot of problems with the code. You are using VLA:s that are not valid in C++ and you also have a lot of <= in your loops that makes your index variables reach outside the allocated array (index out of bounds). I'm not quite sure what the code is supposed to do, but here's an attempt at correcting it using valid C++ although I recommend not using using namespace std; for the reasons mentioned here.

I've replaced the body of your function max_nr() with a few standard functions:

I've used std::for_each to apply a functor to each row in the matrix - in this case a lambda taking the row (R) as an argument. The lambda also captures mymax by reference. The lambda calls std::max_element() to find the max element in the row. It finally compares the row max with the previous mymax value using std::max() and stores that result.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>

using namespace std;

// A template replacement for 2D VLA:s that you can use for most types
template<typename T>
using VLA2D = std::vector<std::vector<T>>;

// A helper function to create a VLA2D with the supplied dimensions
template<typename T>
auto make_VLA2D(size_t R, size_t C, const T& init_value = T{}) {
    return VLA2D<T>(R, std::vector<T>(C, init_value));
}

// This will find the max element in a VLA2D
template<typename T>
T max_nr(const VLA2D<T>& M) {
    T mymax = M[0][0];
    std::for_each(M.begin(), M.end(), [&mymax](const std::vector<T>& R) {
        mymax = std::max(mymax, *std::max_element(R.begin(), R.end()));
    });
    return mymax;
}

int main() {
    int R;
    int C;
    std::cout << "Rows:";
    cin >> R;
    cout << endl;
    std::cout << "Cols:";
    cin >> C;
    cout << endl;

    auto M = make_VLA2D<int>(R, C); // create the 2D array of int:s

    // first we will set a aleatory number for each of the holes in the matrix
    for(int i = 0; i < R; i++) { // will move forward one position
        for(int j = 0; j < C; j++) {
            M[i][j] = (rand() % (50 + 1 - 1)) + 1;
        } // end cols
    }     // end rows

    // show function
    for(int i = 0; i < R; i++) { // will move forward one position
        for(int j = 0; j < C; j++) {
            cout << M[i][j] << "||";

        } // end cols
        cout << endl;
    } // end rows

    // wors ; give aleatory number in correcto rows and cols now must stop when
    // will set all equals movin one by one in cols and cels

    for(int i = 0; i < R; i++) {     // will move forward one position
        for(int j = 0; j < C; j++) { // forward col=

        } // end cols
        cout << endl;
    } // end rows

    int max = max_nr(M);
    cout << max << endl;
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

There are so many things wrong it is hard to know where to begin. Take for example:

int M[R][C];
...
for(int i = 0; i <= R; i++) { // will move forward one position
    for(int j = 0; j <= C; j++) {

By looping i <= R and j <= C, you attempt to access element outside the bounds of your array invoking Undefined Behavior.

Next:

int M[R][C];     /* the C++ standard does not provide VLAs */

The C++ standard does not provide Variable Length Arrays. Initialization of a fundamental type must be by defined numeric constant (e.g. #define R 5).

Further, why are you using the fundamental type int for a 2D array to begin with? C++ provide vector as part of the containers library that provides automatic memory management of arrays and also allowing you to create a vector of vectors to simulate a 2D array of any type needed. See std::vector and also visit the Algorithms library.

Since the vector container can grow dynamically, you can simply add values to each row, and then add rows simulating a 2D array as small or as large as you need (up to the limits of the physical memory)

There use is simple. A vector of int is simply declared as:

vector<int> myarray;

You then add values to your array with:

myarray.push_back(int_value);

To simulate a 2D array you simply declare a vector of vectors, e.g.

vector<vector<int>> my2Darray;

To fill the array you simply fill a temp array and then push that back into your vector of vectors, e.g.

#include <vector>
...
    int R, C;
    vector<vector<int>> M;      /* vector of vectors int */
    ...
    for (int i = 0; i < R; i++) {       /* fill array with random values */
        vector<int> tmp;
        for (int j = 0; j < C; j++)
            tmp.push_back(dis(gen));    /* add random to tmp */
        M.push_back(tmp);               /* push tmp back as row in M */
    }

Iterating over the values in M is made simply by using the range based for loop which will automatically traverse each element. For example your //show function can be written using range based for loop as:

    // show function
    for (auto& r : M) {             /* for each row vector r in M */
        for (auto& c : r)           /* for each c int in r */
            cout << setw(3) << c;   /* set fixed width of 3 and output c */
        cout << '\n';               /* tidy up with a newline  */
    }

Next don't use C rand() (which you forgot to seed the random number generator by calling srand() anyway). Instead, C++ provides Uniform Random Number Generator like std::uniform_int_distribution, use them instead, e.g.

#include <random>
...
    std::random_device rd;      /* random seed */
    std::mt19937 gen(rd());     /* standard mersenne_twister_engine */
    std::uniform_int_distribution<> dis(1, 50); /* uniform dist in range */
    ...
            tmp.push_back(dis(gen));    /* add random to tmp */

Putting it altogether, you could do:

#include <iostream>
#include <iomanip>
#include <vector>
#include <random>

using namespace std;

int max_nr (const vector<vector<int>>&);

int main (void) {

    int R, C;
    vector<vector<int>> M;      /* vector of vectors int */
    std::random_device rd;      /* random seed */
    std::mt19937 gen(rd());     /* standard mersenne_twister_engine */
    std::uniform_int_distribution<> dis(1, 50); /* uniform dist in range */

    std::cout << "Rows: ";  /* prompt for R */
    if (!(cin >> R))        /* validate EVERY input */
        return 1;
    std::cout << "Cols: ";  /* prompt for C */
    if (!(cin >> C))        /* ditto */
        return 1;
    cout << endl;

    for (int i = 0; i < R; i++) {   /* fill array with random values */
        vector<int> tmp;
        for (int j = 0; j < C; j++)
            tmp.push_back(dis(gen));    /* add random to tmp */
        M.push_back(tmp);               /* push tmp back as row in M */
    }

    for (auto& r : M) {         /* output simulated 2D array */
        for (auto& c : r)
            cout << setw(3) << c;
        cout << '\n';
    }

    cout << "\nmax: " << max_nr (M) << '\n';  /* output max */
}

int max_nr (const vector<vector<int>>& M)
{
    int max = std::numeric_limits<int>::min();

    for (auto& row: M)
        for (auto& col : row)
            if (col > max)
                max = col;

    return max;
}

Example Use/Output

$ ./bin/vector2Drand
Rows: 5
Cols: 5

 12 41 44 46  3
  6 34 37 38 16
  3 40 19 10  7
 41 28 47 20 11
 21 30 45 35 14

max: 47

Look things over and let me know if you have questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • I messed up with a lot of things. Its everything clear I´m really thankful. I thought about the #include vector but i consider, is only for one row or one cell. I'm really thankful and sorry for all my mistakes. – Vlad Constantin Podar Apr 04 '19 at 18:28
  • It takes a little white to make friends with the containers library, but once you do you will be really glad you did. The auto memory-management is a thing of beauty and there are many more things vector can do, e.g. [std::vector](https://en.cppreference.com/w/cpp/container/vector) – David C. Rankin Apr 04 '19 at 18:30
  • Sorry for bothering again but i will let here the link where i saw some example of i tryed to used, maybe i took wrong the idea [link] (https://www.programiz.com/cpp-programming/examples/matrix-multiplication-function) – Vlad Constantin Podar Apr 04 '19 at 18:57
  • Give me a second and I"ll take a look. I see they are using the old `int` arrays. (just compiling I see 4-unused variables -- sloppy coding...) – David C. Rankin Apr 04 '19 at 19:08
  • Any time you find code on the internet that compiles with warnings (you always compile with `-Wall -Wextra -pedantic` (gcc/clang) and `/W3` for VS), that code should be viewed skeptically. Here the problem is `‘rowSecond’` should be removed from the parameters of `multiplyMatrices()` altogether and removed from the declaration and call in `main`. After that the code will multiply two matricies. However, the code is so lacking in input validation and so lacking in formatting and sloppy with the use of variables -- I'd keep searching for some better code. – David C. Rankin Apr 04 '19 at 20:11