用于成对比较和跟踪 max/longest 序列的 STL 算法

STL algorithms for pairwise comparison and tracking max/longest sequence

考虑这个相当简单的算法问题:

Given an array of (unsorted) numbers, find the length of the longest sequence of adjacent numbers that are increasing. For example, if we have {1,4,2,3,5}, we expect the result to be 3 since {2,3,5} gives the longest increasing sequence of adjacent/contiguous elements. Note that for non-empty arrays, such as {4,3,2,1}, the minimum result will be 1.

这个有效:

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

template <typename T, typename S>
T max_adjacent_length(const std::vector<S> &nums) {
  if (nums.size() == 0) {
    return 0;
  }
  T maxLength = 1;
  T currLength = 1;

  for (size_t i = 0; i < nums.size() - 1; i++) {
    if (nums[i + 1] > nums[i]) {
      currLength++;
    } else {
      currLength = 1;
    }
    maxLength = std::max(maxLength, currLength);
  }
  return maxLength;
}

int main() {
  std::vector<double> nums = {1.2, 4.5, 3.1, 2.7, 5.3};
  std::vector<int> ints = {4, 3, 2, 1};
  std::cout << max_adjacent_length<int, double>(nums) << "\n"; // 2
  std::cout << max_adjacent_length<int, int>(ints) << "\n"; // 1
  return 0;
}

作为我自己的练习,我想知道是否有 is/are STL 算法可以达到相同的效果,从而(理想情况下)避免我拥有的原始 for 循环。这样做的动机是为了更多地了解STL算法,并练习使用抽象算法使我的代码更通用和可重用。

这是我的想法,但它们完全实现了我想要的。

有没有我忽略的 idea/solution 以简洁易读的方式实现我想要的东西?

在您的两个代码片段中,您都在遍历一个范围(在第一个版本中,使用 index-based-loop,在第二个版本中使用 range-for 循环)。如果你想使用标准算法,这不是你真正应该编写的代码,它与范围内的迭代器一起工作。如果您开始考虑成对的迭代器,而不是将范围视为元素的集合,那么选择正确的算法会变得更容易。

对于这个问题,下面是一个合理的代码写法:

auto max_adjacent_length = [](auto const & v)
{
    long max = 0;
    
    auto begin = v.begin();
    
    while (begin != v.end()) {
        auto next = std::is_sorted_until(begin, v.end());
        max = std::max(std::distance(begin, next), max);
        begin = next;              
    }
    
    return max;
};

这是一个demo

请注意,您在选择合理算法方面已经走在了正确的轨道上。这也可以用 adjacent_find 解决,只需多做一点工作。