在 C++ 矩阵中查找最大元素的索引?

Posted

技术标签:

【中文标题】在 C++ 矩阵中查找最大元素的索引?【英文标题】:Finding the index of the maximum element in c++ matrix? 【发布时间】:2013-07-02 17:26:20 【问题描述】:

我正在将一个 python(sage) 程序翻译成一个 C++ 程序。

我需要编写一个操作矩阵的函数,我需要找到矩阵中最大元素的索引

我想尽可能高效地做到这一点,但到目前为止我想出的唯一方法似乎效率很低。

我的算法的伪代码是,

    给定一个矩阵,在每一行中调用 max_element 函数 创建一个向量并 push_back 从 max_element 返回的迭代器 取消对迭代器的引用,再次调用 max_element 函数 查找列的索引 查找行的索引

这将非常混乱和缓慢.. 有没有人有更好的算法来完成这项任务? 谢谢。

【问题讨论】:

是向量 >,矩阵是随机生成的,传入这个函数 在第 2 步中,创建一个堆,而不是一个向量。 @Nick,我也考虑过,但当时我无法获取该列的索引。 你可以在一个priority_queue(堆)上编写自己的比较对象,创建一个带有索引和值的结构体,并根据值进行比较。 【参考方案1】:

自己编写外循环可能最简单:

if (matrix.size() == 0 || matrix[0].size() == 0) 
    // matrix is empty, handle special case
    throw std::logic_error("empty");

int best = matrix[0][0];
size_t rowidx = 0, colidx = 0;
for (auto it = matrix.begin(); it != matrix.end(); ++it) 
    auto maxit = max_element(it->begin(), it->end());
    if (*maxit > best) 
        best = *maxit;
        rowidx = it - matrix.begin();
        colidx = maxit - it->begin();
    

或者,您可以编写一个迭代整个矩阵的迭代器类:

struct MatrixIterator : std::iterator<std::forward_iterator_tag, int> 
    typedef vector<vector<int> > Matrix;
    Matrix &m;
    size_t rowidx, colidx;
    explicit MatrixIterator(Matrix &m, size_t row = 0, size_t col = 0) : m(m), rowidx(row), colidx(col) ;
    int &operator*()  return m[rowidx][colidx]; 
    MatrixIterator &operator++() 
        ++colidx;
        if (colidx == m[rowidx].size()) 
            colidx = 0;
            ++rowidx;
        
        return *this;
    
    MatrixIterator operator++(int) 
        MatrixIterator result = *this;
        ++*this;
        return result;
    
    bool operator==(const MatrixIterator &rhs) 
        return rowidx == rhs.rowidx && colidx == rhs.colidx;
    
    bool operator!=(const MatrixIterator &rhs) 
        return ! (*this == rhs);
    
    static MaxtrixIterator end(Matrix &m) 
        return MatrixIterator(m, m.size() - 1, m.back().size());
    
;

现在你可以这样做了:

MatrixIterator result = std::max_element(MatrixIterator(m), MatrixIterator::end(m));
size_t rowidx = result.rowidx, colidx = result.colidx;

【讨论】:

谢谢。这有帮助。实际上,我必须在矩阵中找到最大元素的索引,然后继续到下一个子矩阵(从(1,1)到(n,n)),然后到下一个子矩阵((2,2)到(n,n))等等,直到我做最后一个((n-1,n-1)到(n,n))。你认为这仍然是最好的方法吗? 哦,我想如果我在第一个函数之外再添加一个带有 (int i = 0; i @user2418202:是的,我编写的任何一段代码都可以调整为仅对右下角的子矩阵进行操作。从行 k 开始,在每一行中,从列 k 而不是 0 开始。如果我关心效率,我可能会以相反的顺序计算它们。较大矩阵的最大值是较小矩阵的最大值,或者是额外行和列的最大值,因此您总共可以做更少的工作。不过,这对缓存不太友好,所以也许可以进一步改进。 最后一个问题。这不是倒过来了吗?在我看来, colidx = it - matrix.begin();和 rowidx = maxit - it->begin();,但你写的是 rowidx = it - matrix.begin(); colidx = maxit - it->begin(); @user2418202:您可以选择矩阵表示,每个向量代表一行还是一列。我假设它代表一行,因此从 matrix.begin() 开始的迭代器会计算行数。如果你的矩阵是相反的,那很好,相应地调整。【参考方案2】:

我假设您将数据存储在二维向量中。

#include <vector>
#include <algorithm>
vector<vector<int>> Matrix

你应该能够像这样迭代你的矩阵以获得最大的元素

int MaxValue = 0;
for(int i = 0; i < Matrix.size(); i++) 
    if( *std::max_element(Matrix[i].begin(),Matrix[i].end()) < MaxValue ) continue;
    MaxValue = *std::max_element(Matrix,Matrix+Columns);

【讨论】:

以上是关于在 C++ 矩阵中查找最大元素的索引?的主要内容,如果未能解决你的问题,请参考以下文章

在openCV矩阵中查找列最大值的索引和值

获取R中矩阵每一行中K个最小或最大元素的索引

查找矩阵最小元素的 2 个或多个索引(行和列)

在矩阵中查找最小值的索引

在二分查找中,为啥不先检查要查找的元素是不是小于或大于数组的最小或最大索引?

在列表python中查找最小和最大元素的最后一个索引