需要帮助编写一个函数来查找 N 维数组 C++ 中的最大值和最小值

Posted

技术标签:

【中文标题】需要帮助编写一个函数来查找 N 维数组 C++ 中的最大值和最小值【英文标题】:Need help to write a function to find max and min value in a N-dimensional array C++ 【发布时间】:2014-08-13 22:28:24 【问题描述】:

我需要在我的程序中找到不同维度的数组(将是 1-d、2-d 和最多 N 维数组)的最大值和最小值。

谁能帮我写一个函数或函数模板,可以输入任意维度数组并找到最大值/最小值? * 我正在使用向量的向量 像这样的:

#include <vector>
    <template T>
int find_max(T target_array, int dimension);
int main() 
    using namespace std;
    vector<int> array_1d = 1,3,4;
    vector<vector<int> array_2d = 1,3,3,5,2,6,4;
    vector<vector<vector<int>>> array_3d = 1,3,2,4,5,6,7,2,3;
    cout << "Max in 1d array: " << find_max<vector<int>>(array_1d, 1) << endl;
    cout << "Max in 2d array: " << find_max<vector<vector<int>>(array_2d, 2) << endl;
    cout << "Max in 3d array: " << find_max<vector<vector<vector<int>>>>(array_3d, 3) << endl;  
    return 0;          

输出:

Max in 1d array: 4
Max in 2d array: 6
Max in 3d array: 7
Program ended with exit code: 0

谢谢

【问题讨论】:

vector&lt;vector&lt;int&gt;&gt; 不应用作二维数组。如果您将元素保存在连续的内存中,您可以使用std::minmax_element 数组还是向量?向量的向量甚至可能在每个子维度上都没有相同的深度,即 1,2,3,3,5,6 嗨 Snpa,我不知道如何使用 1 个函数来处理不同的输入,我现在正在做的是为不同的维度编写不同的函数... 嗨 Cristian Niculescu,是的,这就是问题所在,让我头疼的是它是向量的向量,它具有不同的深度..... 使用vector&lt;vector&lt;int&gt;&gt; 作为二维数组是可以的。它是否最佳取决于你将用它做什么。它的主要优点是使用起来非常简单明了。 【参考方案1】:

您编写签名的函数可以通过对std::max_element的简单调用来实现。

然后您可以使用接受任何嵌套向量的模板重载此函数,该模板首先将函数递归地应用于向量的每个元素,然后再计算它们的最大值。

下面的代码实现了这个想法。第二个参数int dimension 不是必需的,因为维数由第一个参数的类型给出。

如果您同时需要最小和最大元素,您可以使用 std::minmax_element 之类的基本情况,但递归调用会变得更加复杂。

现场演示:http://ideone.com/kW0ewz

// Forward-declare
template<class T>
int find_max(std::vector<std::vector<T> > target_array);

// First, define the base case
int find_max(std::vector<int> target_array) 
    using namespace std;

    return *max_element(
        target_array.begin(),
        target_array.end());


// Then the general case
template<class T>
int find_max(std::vector<std::vector<T> > target_array) 
    using namespace std;

    // Reserve a vector for the recursive call
    vector<int> reduced(target_array.size());

    // Recursively apply this function to each nested vector
    transform(
        target_array.begin(),
        target_array.end(),
        reduced.begin(),
        [](std::vector<T> v) return find_max(v); );

    // Then find the maximum of the reduced vector
    return *max_element(
        reduced.begin(),
        reduced.end());

【讨论】:

虽然这在家庭作业设置中很优雅且很好,但请注意,对 N 维矩阵使用它会自动生成 N 个 find_max 函数实现。在生产代码中谨慎使用。 谢谢你!我刚刚从您的示例中学会了如何使用std::transform @CristianNiculescu 为什么这会是个问题?只要N 是一个小数字,我的意思是可能低于100,它就不会破坏你的程序,无论是在实验还是生产使用中。 (我的意思是,100 维向量......请注意,矩阵总是有 2 个维度。同样,不要将维度与大小混淆。)【参考方案2】:

这是另一个如何完成的最小示例:

int find_max(int i) 
    return i;


template <typename T>
int find_max(const std::vector<T>& v) 
    return std::accumulate(std::begin(v), std::end(v),
        std::numeric_limits<int>::min(),
        [] (const int prev, const T& v) 
            int m = find_max(v);
            return (m > prev) ? m : prev;
        );

这将适用于任意级别的嵌套std::vectors。

Live example

编辑:

查看更新后的代码(更改了 lambda 内的 return 语句)。以前的版本不能正确处理负数。

【讨论】:

【参考方案3】:

请注意,模板函数可以派生其参数类型。您无需指定调用方法的类型;并且您可以让他们为您驱动他们的调用参数(模板结构并非如此)。你可以利用它。

这是另一个解决方案:

int find_max(int a)  return a;  // Just a base case for recursion
template<typename T>
int find_max(const std::vector<T>& v)

   int r = find_max(v.front());
   for (auto i=v.begin()+1, e=end()
       ; i<e
       ; ++i)
   
      int c = find_max(*i);
      if (c>r) r=c;
   
   return r;

不管你有多少嵌套向量,用法都是一样的:

cout << "Max in 1d array: " << find_max(array_1d) << endl;
cout << "Max in 2d array: " << find_max(array_2d) << endl;
cout << "Max in 3d array: " << find_max(array_3d) << endl;  

...STL 方法更侧重于在 T 的容器中为您提供最大 T;如果我们要嵌套 T,我们必须递归两次才能取出根元素(一次告诉我们哪个 T 具有最大值,然后再次提取它)。这里的方法是简单的自底向上递归(每个 find_max 都会为您提供该级别结构的最大值,我们只是涓涓细流)。

【讨论】:

以上是关于需要帮助编写一个函数来查找 N 维数组 C++ 中的最大值和最小值的主要内容,如果未能解决你的问题,请参考以下文章

面试题:编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。(c++实现)

编写一个算法来查找数组中出现频率最高的元素。给出算法的时间复杂度

如何编写一个函数来并行查找大于 N 的值

默认类构造函数 C++ 遇到问题

C++ 如何使用和传递一个 3 维字符数组?

2021-09-15:最长公共前缀。编写一个函数来查找字符串数组中的最长公共前缀,如果不存在公共前缀,返回空字符串 ““。力扣14。