找到向量中的最小值

问题描述 投票:0回答:2

下面我附上了一个项目的代码,该项目旨在查找用户输入向量中的最小值,如果向量为空则返回 -1,如果向量只有一个索引则返回 0。我遇到了向量为空的情况的问题,因为单元测试继续未能通过 returns_negative_one_for_empty_vector 测试。

main.cc

#include <iostream>
#include <vector>
#include "minimum.h"

int main() {
  int size;
  std::cout << "How many elements? ";
  std::cin >> size;
  std::vector<double> numbers(size);

  for (int i = 0; i < size; i++) {
    double value;
    std::cout << "Element " << i << ": ";
    std::cin >> value;
    numbers.at(i) = value;
  }
 
  double index;
  index = IndexOfMinimumElement(numbers);

  std::cout << "The minimum value in your vector is at index" << index << std::endl;
}

最低.cc

#include "minimum.h"
#include <vector>

int IndexOfMinimumElement(std::vector<double> input) {
  int i, min_index;

  double min_ = input.at(0);

  for (int i = 0; i < input.size(); i++) {
    if (input.at(i) < min_) {
      min_index = i;

      return min_index;
    }
    else if (input.size() == 0) {
      return -1;
    }
    else if(input.size() == 1) {
      return 0;
    }
  }
};

最小.h

#include <vector>

int IndexOfMinimumElement(std::vector<double> input);
c++ vector
2个回答
3
投票

找到用户输入向量中的最小值,如果满足则返回-1 向量为空,如果向量只有一个索引,则为 0。

无需编写原始

for
循环,通过使用 STL 算法函数可以更轻松地完成

还有其他问题,其中一个是向量应该通过

const
引用传递,而不是通过值传递。 按值传递向量会产生不必要的副本。

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

int IndexOfMinimumElement(const std::vector<double>& input) 
{
    if (input.empty()) 
        return -1;
    auto ptrMinElement = std::min_element(input.begin(), input.end());
    return std::distance(input.begin(), ptrMinElement);
}

int main() 
{
    std::cout << IndexOfMinimumElement({ 1.2, 3.4, 0.8, 7.8 }) << std::endl;
    std::cout << IndexOfMinimumElement({}) << std::endl;  // empty
    std::cout << IndexOfMinimumElement({3}) << std::endl; // only 1 element
    return 0;
}

输出:

2
-1
0

相关函数是std::min_elementstd::distance

std::min_element
返回一个指向范围内最小元素的迭代器(类似于指针)。

代码的编写清楚地了解了每个函数的作用——它实际上是自我记录的。 要获取最小元素,请调用

std::min_element
。 要获取从第一个到找到的最小元素的距离,您可以调用
std::distance
,并使用一个到起始位置的迭代器和一个到结束位置的迭代器。

底线是:当给定正确的输入参数时,STL 算法很少(如果有的话)运行失败。 正如您所见证的,编写原始

for
循环总会有更大的失败机会。 因此,我们的目标是尽量减少编写此类
for
循环。


0
投票

IndexOfMinimumElement
中,您在第一次迭代时
return
,因为 if/else 的所有分支都会导致返回。

如果您的向量包含

{14, 2, 10, 1}
,则它将返回的索引为
1
,因为
2
小于
14

相反,您希望在函数顶部进行一些条件检查,这些检查根据向量的长度返回。

如果函数调用超过了这些值,它应该迭代向量中的值,检查它们是否小于运行最小值,并相应地更新最小索引。

int IndexOfMinimumElement(std::vector<double> input) {
    if (input.size() == 0) return -1;
    if (input.size() == 1) return 0;

    int i = 0;
    double min = input[0];
    int min_idx = 0;

    for (auto &v : input) {
        if (v < min) {
            min = v;
            min_idx = i;      
        }    

        ++i;
    }

    return min_idx;
}

最小测试:

int main() {
    std::vector<double> foo { 1.2, 3.4, 0.8, 7.8 };

    std::cout << IndexOfMinimumElement(foo) << std::endl;

    return 0;
}

打印,如预期:

2

考虑让你的函数返回一个 可选

std::size_t
值,而不是在未找到的情况下返回带有
int
-1
。您也可以将其设为模板函数,这样它就不必只处理
double
值的向量。

template <typename T>
std::optional<std::size_t> IndexOfMinimumElement(std::vector<T> input) {
    if (input.size() == 0) return std::nullopt;
    if (input.size() == 1) return 0;

    std::size_t i = 0;
    T min = input[0];
    std::size_t min_idx = 0;

    for (auto &v : input) {
        if (v < min) {
            min = v;
            min_idx = i;      
        }    

        ++i;
    }

    return min_idx;
}

int main() {
    std::vector<double> foo { 1.2, 3.4, 0.8, 7.8 };

    std::cout << IndexOfMinimumElement(foo).value_or(-1) << std::endl;

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.