【问题标题】:Simultaneous minimum and maximum同时最小和最大
【发布时间】:2013-10-22 12:12:37
【问题描述】:

我尝试实现一种算法,该算法将在给定数组中搜索最小和最大元素,并使用了 Cormen 的算法简介中的想法。我的代码编译并开始工作,输出生成的随机数组,然后很长一段时间什么都不做。 为什么会这样?

代码是这样的:

// fast min and max --cormen exercise 1.cpp: entry point
//implemented from a verbal description in cormen's book, p 243

#include "stdafx.h"
#include <vector>
#include <ctime>
#include <cstdlib>
#include <iostream>

struct min_and_max
{
    int min, max;
};


min_and_max find_min_and_max(std::vector<int>& A)
{
    int n = A.size();
    int min, max;
    if (n%2 == 1)
        min = max = A[0];
    if (n%2 == 0)
        if (A[0] < A[1])
        {
            min = A[0];
            max = A[1];
        }
        else
        {
            min = A[1];
            max = A[0];
        }
    for(int i = 2; i < A.size(); (i + 2))
    {
        if (A[i] < A[i+1])
        {
            if (min > A[i])
                min = A[i];
            if (max < A[i+1])
                max = A[i+1];
        }
        else
        {
            if (min > A[i+1])
                min = A[i+1];
            if (max < A[i])
                max = A[i];
        }
    }
    min_and_max result;
    result.min = min;
    result.max = max;

    return result;
}

int main()
{
    std::srand(std::time(0));
    std::vector<int> A(10);
    for (auto i = 0; i < A.size(); i++)
        {
            A[i] = rand() % 1000;
            std::cout << A[i] << " ";           
        }
    std::cout << std::endl; //IT GOES AS FAR AS THIS
    std::cout << "The array has been analyzed; its' minimum is " << find_min_and_max(A).min << "and its' maximum is " << find_min_and_max(A).max << std::endl;

    return 0;
}

【问题讨论】:

  • 附带说明,您可以使用std:pair&lt;int, int&gt; 来存储最小值和最大值,而不是创建自己的对,也可以使用typedef pair&lt;int, int&gt; min_and_max
  • 现在代码运行正常,我想知道:我在此代码的先前版本中使用过std::pair,然后我不知何故觉得struct 更快。真的吗?
  • @Chiffa: std::pair 是一个与您使用的结构几乎相同的结构;此外,您的函数使用的时间主要由寻找最小值/最大值的循环控制,返回类型的差异无论如何都可以忽略不计。
  • 循环还不够吗? int maxval = INT_MIN; int minval = INT_MAX; for (auto&amp; i : A ) { maxval = std::max( maxval, i ); minval = std::min( minval, i ); }
  • 您的结构与std::pair 相同,但成员名称更好。

标签: c++ algorithm max minimum


【解决方案1】:
 for(int i = 2; i < A.size(); (i + 2))

i + 2不会改变i的值,你需要使用i += 2

【讨论】:

  • 谢谢,我真的不知道如何正确写这个增量。
  • 通常我们使用 i++ 编译器将其解释为 2 个事物返回 i 并增加它。 stackoverflow.com/questions/24853/…
  • @Nishant i++ 用于将其增加 1,最好是 ++i
【解决方案2】:

问题出在这里:

for(int i = 2; i < A.size(); (i + 2))

您从未真正增加i,从而导致无限循环。

改成:

for(int i = 2; i < A.size(); i+=2)

【讨论】:

    【解决方案3】:

    除了给定的答案之外,如果您使用的是 c++11,您可以使用 lambdasstd::for_each 函数来简化您的算法:

    #include <algorithm>
    #include <iostream>
    #include <cmath>
    
    int main() { 
        int array[] = { -8, 8, 0, 9, 5, -3, 4, 6, -1, 15, 31 };
        int min, max;
        // User std::for_each(v.begin(), v.end(), ...) for either vector or list
        std::for_each(std::begin(array), std::end(array), [&min, &max](int elem) { 
            max = std::max(max, elem);
            min = std::min(min, elem);
        });
        std::cout << min << ", " << max << std::endl;
        return 0;
    }
    

    也许它可以更简单

    更新:正如@Blastfurnace 指出的那样,std::minmax_element 函数可用于进一步减少搜索 min 和 max 元素所需的代码,从而产生这个更短的版本:

    #include <algorithm>
    #include <iostream>
    #include <vector>   
    
    int main() { 
        std::vector<int> values = { -8, 8, 0, 9, 5, -3, 4, 6, -1, 15, 31 };
        auto minAndMax = std::minmax_element(values.begin(), values.end());
        std::cout << *minAndMax.first << ", " << *minAndMax.second << std::endl;
        return 0;
    }
    

    重要的是要注意,除了作为 OT 之外,此答案中所做的一切都是为了学习,为 OP 提供替代方案以改进他(或她)的工作并帮助其他可能拥有相同的用户要求。

    【讨论】:

    • 如果您使用的是C++11,则使用std::minmax_element 可能更有意义
    • 就我个人而言,就像 lambdas 一样,我可能会使用它们。至于std::minmax_element,它以我不确定是否需要这个特定代码的方式处理几个等效元素。
    • @Chiffa:我也认为 lambdas 很棒,但std::minmax_element 执行的比较次数最少,这是正确的,而且它是我不必重新发明的库代码。
    • 关于更新 -- 这真的很有教育意义,我会稳步改进我的解决方案。
    【解决方案4】:

    在任何情况下,算法都是不正确的,因为向量的大小可能等于 0。在这种情况下,1)您尝试访问不存在的元素,以及 2)您从函数返回未定义的值。更正确的方法是返回最小和最大元素的索引,如果向量为空,则返回一对 A.size()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      相关资源
      最近更新 更多