【问题标题】:Function to get minimum of three or more arguments [closed]获取最少三个或更多参数的函数[关闭]
【发布时间】:2013-08-31 13:06:06
【问题描述】:

在 C 语言的 <math.h> 库中,函数 fmin(x,y) 返回两个参数 x 和 y 的最小值,如 the C++ reference 中所述。

但是,是否有类似的函数fminimum(a,b,c,...x,y,z) 可以找到相同数据类型的三个或更多参数中的最小值?

【问题讨论】:

  • 您的标题显示“in C”,但您的标签包含 C++。您是否允许使用 C++ 解决方案?
  • @mbratch 好的,抱歉,此时只有 C
  • 使用可变参数可以做到这一点,但是你必须提供额外的参数来告诉你传递了多少个数字,或者使用一些特殊的值,例如 NaN 来表示最后一个数字。

标签: c minimum math.h


【解决方案1】:

注意:该问题最初标记为 C++。原始答案仅适用于 C++,但我提供了遵循相同原则的 C 解决方案。

这个想法是将表示范围开始和结束的一对指针传递给函数,并返回指向最小元素的指针。

int* min_element(int *start, int *end)
{
    if (start == end) return end;

    int *min = start++;
    for (; start != end; ++start)
        if (*start < *min) min = start;

    return min;
}

用法:

int data[] = {1, 5, 3, 66, 4, 81, 23, 2, 6};
int * min = min_element(data, data + 9);
if (min != data + 9)
{
  // range was not empty, min value is *min
}

C++回答std::min_element,它为您提供了一个迭代器,指向由一对迭代器指定的范围内的最小元素。

int arr[] = { 3,1,6,8,9,34,17,4,8};
auto it = std::min_element(std::begin(arr), std::end(arr));

编辑 2:从已删除的答案中,C++11 有一个 std::min 重载,它需要一个 initializer_list,所以你可以说

auto minval = std::min({a, b, c, x, y, z});

其中abc 等都是支持operator&lt; 的一种类型。

【讨论】:

  • 不幸的是,OP 只想要C
  • @mbratch 太糟糕了,他们最初将问题标记为 C++,然后 :)
  • @juanchopanza 确实,这就是我在评论中询问 OP 的原因。
  • @mbratch,如果他们使用“C++ 参考”,我认为他们的意思是 C++:/
  • @chris 是的,这不是一个措辞很好的问题。
【解决方案2】:

老式的方式...

int arr[] = { 1, 3, 6, 100, 50, 72 };

int min_array( int arr[], int len )
{
    int min = arr[0];

    for ( int i = 1; i < len; i++ )
        if ( arr[i] < min )
            min = arr[i];

    return min;
}

【讨论】:

    【解决方案3】:

    “任意数量的参数”的问题是你怎么知道有多少。

    std::minstd::min_element 通过在容器上工作来解决这个问题 - 换句话说,我们知道有多少,这要归功于容器对象本身知道有多少。

    在纯 C 语言中,你不能真正做到这一点。所以需要有其他的方法。

    一种方法是使用&lt;cstdarg&gt;,并用特殊值标记结尾:

    #include <iostream>
    #include <cstdarg>
    
    using namespace std;
    
    int countargs(int arg, ...)
    {
        if (arg == -1)
        return 0;
    
        int count = 1;   // arg is not -1, so we have at least one arg.
        va_list vl;
        int cur;
        va_start(vl, arg);
        for(;;)
        {
        cur = va_arg(vl, int);
        if(cur == -1)
            break;
        count++;
        }
        va_end(vl);
        return count;
    }
    
    
    int main()
    {
        cout << "Should give 0: " << countargs(-1) << endl;
        cout << "Should give 1: " << countargs(1, -1) << endl; 
        cout << "Should give 3: " << countargs(1, 2, 3, -1) << endl;
        cout << "Should give 6: " << countargs(1, 2, 3, 1, 2, 3, -1) << endl;
        cout << "Should give 12: " << countargs(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, -1) << endl;
        return 0;
    }
    

    上面没有显示如何获得min 值,但应该不难弄清楚。它也是 C++,但不依赖于任何特殊的 C++ 功能。

    “标记结束”的替代方法是将元素的数量传递给函数本身。

    当然,如果参数在数组中,真正的解决方案是遍历它们。如果没有那么多,你当然可以使用:

    v = min(a, min(b, min(c, d)));; 
    

    【讨论】:

      【解决方案4】:

      唯一可以做到这一点的 libc 函数会做得更多,因为它会排序,这可以被认为是矫枉过正。我是qsort()

      【讨论】:

        猜你喜欢
        • 2015-02-22
        • 2021-06-27
        • 2015-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-13
        相关资源
        最近更新 更多