c ++函数返回向量中的最小正整数

Posted

技术标签:

【中文标题】c ++函数返回向量中的最小正整数【英文标题】:c++ function return the smallest positive integer in a vector 【发布时间】:2018-04-09 09:26:46 【问题描述】:

我正在使用下面的代码,它返回向量中的最小正整数。我得到了代码here。我的问题是有理由将大小传递给函数,你可以不在函数体中计算它吗?

第二个if() 测试是为了什么?我不明白这个 if 语句是如何工作的?

#include <vector>
using namespace std;
int rec_min_pos(const vector<int> & nums, int size) 
    if (size < 1) 
        return INT_MAX;
    
    if(nums[size-1] > 0)
        return min(nums[size-1], rec_min_pos(nums, size-1));
    
    else
        return rec_min_pos(nums, size-1);
    

【问题讨论】:

size 参数应该命名为 index 或其他名称。这很令人困惑,因为它与向量的大小没有任何关系。 向量知道它们有多大。但请注意,该函数是递归的,它不会每次都对整个向量进行操作。 size 参数可能可以命名为last_elem,这是必要的,因为该函数以递归方式而不是循环工作。它实际上不是向量的大小,而是函数将搜索最小正元素的向量部分(第一次调用应该是完整大小,递归调用会查找更小的部分)。第二个 if 检查最后一个元素是否为负数,否则返回向量下一部分中找到的最佳值。 当您忽略 size 参数并改用 nums.size() 时发生了什么?你从中学到了什么?哦,是的,当您在调试器中单步执行程序时看到了什么? 顺便说一句,编写这样的递归函数不是很明智。更喜欢涉及std::min_element 和合适谓词的东西。 (例如[](int lhs, int rhs) return std::tie(!std::signbit(lhs), lhs) &lt; std::tie(!std::signbit(rhs), rhs) . 【参考方案1】:

第二个if 语句检查元素的正数,因为函数应返回最小的正数整数。

您的函数是递归的,'size' 参数实际上是要测试的最后一个元素的索引的加一。这允许一个简单的递归函数设计,但需要一个额外的参数。在函数接口中明确说明这些点可能会更好

inline int recursive_min_positive(const int*arr, size_t i)

    return 
        i==0? std::numeric_limits<int>::max() :
        arr[i-1]<=0? recursive_min_positive(arr,i-1) :
        std::min(arr[i-1],recursive_min_positive(arr,i-1) ;


int min_positive(std::vector<int> const&arr)

    return recursive_min_positive(arr.data(), arr.size());

递归函数设计通常很优雅,但效率低下(尽管编译器倾向于展开递归)。在这里,非递归实现实际上更短更清晰。

int min_positive(std::vector<int> const&arr)

    int result = std::numeric_limits<int>::max();
    for(auto val : arr)
        if(0 < val  &&  val < result) result = val;
    return result;

【讨论】:

【参考方案2】:

除了所有的 cmets:你可以像这样重载函数:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// Original function with size argument
int rec_min_pos(const vector<int> & nums, int size) 
  if (size < 1) 
    return INT_MAX;
  
  if (nums[size - 1] > 0) 
    return min(nums[size - 1], rec_min_pos(nums, size - 1));
  
  else 
    return rec_min_pos(nums, size - 1);
  


// Overloaded rec_min_pos function
int rec_min_pos(const vector<int> & nums) 
    // here we just call the original rec_mon_pos function
    return rec_min_pos(nums, nums.size());


int main()

  vector<int> v 9,2,7,3,7,5,6 ;
  cout << rec_min_pos(v);  // call the overloaded function

输出:

2

【讨论】:

谢谢你的建议,这不编译你正在传递 2 个参数 return rec_min_pos(nums, nums.size());? @arcoxiatom 我将截取的代码更改为完整的可编译示例。【参考方案3】:

与递归函数无关,但扩展了我的评论:

int min_positive(std::vector<int> & nums)

    auto elem = std::min_element(nums.begin(), nums.end(), 
        [](int lhs, int rhs) return std::tie(std::signbit(lhs), lhs) < std::tie(std::signbit(rhs), rhs); 
    );
    if ((elem == nums.end()) || std::signbit(*elems))  return MAX_INT; 
    return *elem;

这里我们定义了一个比较函数,将正数排序在负数之前,然后按值排序。我们使用三个参数std::min_element,它将在nums 中找到一个迭代器。

第一个检查处理一个空的nums,第二个检查每个值都是负数,这两者都被原始忽略,返回MAX_INT

【讨论】:

以上是关于c ++函数返回向量中的最小正整数的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个给定正整数的函数,返回一个向量,该向量的数字是 5 的倍数?

C++_求2个或3个正整数中的最大数,用带有默认参数的函数实现

C语言,设计函数int max(int num); 函数功能:依次分解出正整数num的各位数字,返回最大数字

C语言 在文件中存放的均为40至60之间的正整数,要求统计每个正整数出现的次数,按次数升序排序并输出?

C语言编程:输入两个正整数m和n,求它们的最大公约数。

C语言编程:输入两个正整数m和n,求它们的最大公约数。