为啥建议从矩阵中获取最大值的函数->无法将'int(*)[C]'转换为'int(*)[0]

Posted

技术标签:

【中文标题】为啥建议从矩阵中获取最大值的函数->无法将\'int(*)[C]\'转换为\'int(*)[0]【英文标题】:Why a function to get a max value from a matrix is advising ->cannot convert ‘int (*)[C]’ to ‘int (*)[0]为什么建议从矩阵中获取最大值的函数->无法将'int(*)[C]'转换为'int(*)[0] 【发布时间】:2019-04-04 17:22:25 【问题描述】:

我试图设置一个随机值在 0-50 之间的矩阵,然后创建一个算法,该算法不会停止,直到矩阵的行和列具有相同的数字 1 一个。使用#include 并创建一个函数来获取最大值在获取最大值时主要不起作用。

控制台: 错误:无法将参数 '1' 的 'int ()[C]' 转换为 'int ()[0]' 到 'int max_nr(int (*)[0], int, int) ' 我尝试了不同的方法来调用函数 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;

【问题讨论】:

这不是有效的 C++ 代码。 C++ 中没有变长数组。 为什么有一个函数采用长度为零的数组? 为了获得最大值,我们有std::max_element。另外,请查看 std::arraystd::vector 以替代糟糕的旧 C 样式数组。 max_nr 应该做什么?你想在那个函数中用*std::max_element(M[i], M[j])做什么? 我会把我看到的一些我尝试使用的例子的链接放在这里,也许我错了[链接] (programiz.com/cpp-programming/examples/…) 【参考方案1】:

有很多事情是错误的,很难知道从哪里开始。举个例子:

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

通过循环i &lt;= Rj &lt;= C,您尝试通过调用未定义的行为访问数组边界之外的元素。

下一步:

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

C++ 标准不提供可变长度数组。基本类型的初始化必须通过定义的数字常量(例如#define R 5)。

此外,您为什么要使用基本类型int 作为二维数组开始? C++ 提供 vector 作为容器库的一部分,它提供数组的自动内存管理,还允许您创建 vector 的vector 来模拟所需的任何类型的 2D 数组。请参阅std::vector 并访问Algorithms library。

由于向量容器可以动态增长,您可以简单地为每一行添加值,然后添加模拟二维数组的行,无论大小(不超过物理内存的限制)

那里使用很简单。 int 的向量简单地声明为:

vector<int> myarray;

然后您将值添加到您的数组中:

myarray.push_back(int_value);

要模拟二维数组,您只需声明一个向量的向量,例如

vector<vector<int>> my2Darray;

要填充数组,您只需填充一个临时数组,然后将其推回向量向量中,例如

#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 */
    

迭代M 中的值只需使用基于范围的for 循环,它会自动遍历每个元素。例如,您的//show function 可以使用基于范围的for 循环编写为:

    // 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  */
    

接下来不要使用 C rand()(无论如何你都忘了通过调用 srand() 来为随机数生成器播种)。相反,C++ 提供了 统一随机数生成器,例如 std::uniform_int_distribution,请改用它们,例如

#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 */

总而言之,你可以这样做:

#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;

使用/输出示例

$ ./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

检查一下,如果您有任何问题,请告诉我。

【讨论】:

我搞砸了很多事情。一切都清楚了,我真的很感激。我考虑过#include 向量,但我认为它仅适用于一行或一个单元格。对于我所有的错误,我真的很感激和抱歉。 与容器库交朋友需要一点小白,但一旦你这样做了,你会很高兴你做到了。自动内存管理是一件很美的事情,vector 可以做更多的事情,例如std::vector 很抱歉再次打扰,但我会在这里提供我看到的一些我尝试使用的示例的链接,也许我错了 [链接] (programiz.com/cpp-programming/examples/…) 等一下,我会看一下。我看到他们正在使用旧的 int 数组。(只是编译我看到 4 个未使用的变量——草率的编码......) 任何时候你在 Internet 上发现编译时带有警告的代码(你总是使用 -Wall -Wextra -pedantic (gcc/clang) 和 /W3 编译 VS),应该怀疑地查看该代码。这里的问题是‘rowSecond’ 应该从multiplyMatrices() 的参数中完全删除,并从main 的声明和调用中删除。之后,代码将两个矩阵相乘。但是,代码在输入验证方面非常缺乏,在格式方面也非常缺乏,并且对变量的使用很草率——我会继续寻找更好的代码。【参考方案2】:

你的代码有很多问题。您正在使用在 C++ 中无效的 VLA:s 并且您的循环中还有很多 &lt;= 使您的索引变量到达分配的数组之外(索引超出范围)。我不太确定代码应该做什么,但这里尝试使用有效的 C++ 来纠正它,尽管我建议使用using namespace std;,原因提到here。

我已将您的函数 max_nr() 的主体替换为一些标准函数:

我使用std::for_each 将仿函数应用于矩阵中的每一行——在本例中,一个 lambda 以行 (R) 作为参数。 lambda 还通过引用捕获mymax。 lambda 调用std::max_element() 来查找行中的最大元素。最后,它使用std::max() 将行最大值与之前的mymax 值进行比较并存储该结果。

#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;

【讨论】:

以上是关于为啥建议从矩阵中获取最大值的函数->无法将'int(*)[C]'转换为'int(*)[0]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 CUDA 代码无法正常工作以零填充大型矩阵?

为啥 MATLAB 会自动将变量转换为矩阵?

从文件中获取矩阵并将其分配给具有最大大小的数组

使用 NumPy 从矩阵中获取最小/最大 n 值和索引的有效方法

opencv中为啥图像局矩阵是以BGR而不是RGB显示像素的大小?

为啥我无法在控制台中查看从数据库中获取的数据