检查数组中的给定 K 元素

Examining a given K element in an array

本文关键字:元素 数组 检查      更新时间:2023-10-16

这个作业是关于湖上的船比赛。

我有一个 N 数组,我在其中输入风速。 我必须给出一个 K 数,它决定了连续多少天的风速在 10 到 100 之间。 如果我找到 K 个连续元素的数量,我必须控制台出这个序列的第一个元素的索引。

目标是找到"比赛"可以开始的哪一天。

例如:

S[10] = {50,40,0,5,0,80,70,90,100,120}
K=3

输出必须为 6,因为它是数组的第 6 个元素,此序列从此元素开始。

我不知道如何实施此检查的任何方法。

我试过这个:

for (int i=0; i<N-2; i++){
if (((10<=S[i]) && (S[i]<=100)) && ((10<=S[i+1]) && (S[i+1]<=100)) && ((10<=S[i+2]) && (S[i+2]<=100))){
canBeStarted = true;
whichDayItCanBeStarted = i;
}
}
cout << whichDayItCanBeStarted << endl;

但我意识到K可以是任何数字,所以我必须立即检查K元素。

利用算法标准库

(限制:以下答案提供了一种适用于C++17 岁及以上)的方法)

对于这样的问题,与其重新发明轮子,不如考虑转向标准库中的算法库,利用std::transformstd::search_n

  • 在风速上产生integer -> bool变换到所述风速的有效性,然后
  • 在变换结果中搜索许多(K)后续true(有效风速)元素,

分别。

例如:

#include <algorithm>  // std::search_n, std::transform
#include <cstdint>    // uint8_t (for wind speeds)
#include <iostream>   // std::cout
#include <iterator>   // std::back_inserter, std::distance
#include <vector>     // std::vector
int main() {
// Wind data and wind restrictions.
const std::vector<uint8_t> wind_speed{50U, 40U, 0U,  5U,   0U,
80U, 70U, 90U, 100U, 120U};
const uint8_t minimum_wind_speed = 10U;
const uint8_t maximum_wind_speed = 100U;
const std::size_t minimum_consecutive_days = 3;
// Map wind speeds -> wind speed within limits.
std::vector<bool> wind_within_limits;
std::transform(wind_speed.begin(), wind_speed.end(),
std::back_inserter(wind_within_limits),
[](uint8_t wind_speed) -> bool {
return (wind_speed >= minimum_wind_speed) &&
(wind_speed <= maximum_wind_speed);
});
// Find the first K (minimum_consecutive_days) consecutive days with
// wind speed within limits.
const auto starting_day =
std::search_n(wind_within_limits.begin(), wind_within_limits.end(),
minimum_consecutive_days, true);
if (starting_day != wind_within_limits.end()) {
std::cout << "Race may start at day "
<< std::distance(wind_within_limits.begin(), starting_day) + 1
<< ".";
} else {
std::cout
<< "Wind speeds during the specified days exceed race conditions.";
}
}

或者,我们可以在std::search_n调用中将转换集成到二进制谓词中。这产生了一个更紧凑的解决方案,但 imo 的语义和可读性稍差一些。

#include <algorithm>  // std::search_n
#include <cstdint>    // uint8_t (for wind speeds)
#include <iostream>   // std::cout
#include <iterator>   // std::distance
#include <vector>     // std::vector
int main() {
// Wind data and wind restrictions.
const std::vector<uint8_t> wind_speed{50U, 40U, 0U,  5U,   0U,
80U, 70U, 90U, 100U, 120U};
const uint8_t minimum_wind_speed = 10U;
const uint8_t maximum_wind_speed = 100U;
const std::size_t minimum_consecutive_days = 3;
// Find any K (minimum_consecutive_days) consecutive days with wind speed
// within limits.
const auto starting_day = std::search_n(
wind_speed.begin(), wind_speed.end(), minimum_consecutive_days, true,
[](uint8_t wind_speed, bool) -> bool {
return (wind_speed >= minimum_wind_speed) &&
(wind_speed <= maximum_wind_speed);
});
if (starting_day != wind_speed.end()) {
std::cout << "Race may start at day "
<< std::distance(wind_speed.begin(), starting_day) + 1 << ".";
} else {
std::cout
<< "Wind speeds during the specified days exceed race conditions.";
}
}

鉴于您提供的特定(硬编码)风数据和限制,上述两个程序都会导致:

Race may start at day 6.

您需要有一个最初设置为0的计数器变量,以及另一个变量来存储序列开始的索引。 并一次循环访问一个元素的数组。如果发现 10 到 100 之间的元素,请检查计数器是否等于"0"。如果是,则将索引存储在另一个变量中。将计数器递增 1。如果计数器等于 K,则您已完成,因此break循环。否则,如果元素不在 10 到 100 之间,请将计数器设置为0