如何保持在矢量范围内

How to stay within vector range?

本文关键字:范围内 何保持      更新时间:2023-10-16

我目前在向量中保持在某个范围内时遇到了一些问题。

在下面的代码中,我试图检查正在检查的数字是小于还是等于它后面的数字

#include <iostream>
#include <vector>
#include <stdexcept>
bool fun(std::vector<int> v)
{
    for(int i = 0; i < v.size(); i++)
    {
        if(v.at(i) <= v.at(i+1))
        {
            // code
        }
    }
    return true;
}
int main()
{    
    std::vector<int> v { 1,2,3,4,5,6,7,8,9 };
    try
    {
        std::cout << fun(v);
    }
    catch(std::out_of_range range_problem)
    {
        std::cout << "EXCEPTION: " << range_problem.what();
    }
    return 0;
}

由于at(),函数抛出异常,所以上面的代码输出如下:

EXCEPTION: vector::_M_range_check

我想过在 for 循环中添加if(i+1 == v.size() - 1) break;,但这意味着我将无法比较该向量中的最后两个元素。

任何人都可以推荐解决此问题的方法吗?

谢谢

在这段代码中:

  for(int i = 0; i < v.size(); i++)
    {
        if(v.at(i) <= v.at(i+1))
        {
            // code
        }
    }

v.at(i+1)将在循环的最后一次迭代中经过向量的末尾。 如果将循环中的条件更改为i < v.size()-1这将解决问题。

一些建议。

如果您的向量只有一个元素怎么办?

这可能永远不会发生,但无论如何我都会检查它。

然后我发现在这些情况下使用两个索引变量更容易,以防我以后需要操作这两个元素。

bool fun(std::vector<int> v)
{
    if (v.size() == 1)
        return true; // Perhaps you would return false?
    for(int i = 0, j = 1; i < v.size() && j < v.size() - 1; i++, j++)
    {
        if(v.at(i) <= v.at(j))
        {
            // code
        }
    }
    return true;
}

以下是我如何编写此代码:

auto prev = begin(v);
auto it = prev;
if(it == end(v))
    return;
it ++;
for(; it != end(v); it++, prev++)
{
    if(*prev <= *it)
    {
        //code
    }
}

有几个好处:

  1. 它将与多种类型的容器一起使用,包括list和数组,如int v[] = {10,20,30,40,50};array<int, 5>

  2. 迭代器只能是前向的,不必是随机访问。

  3. 如果需要索引,仍然可以从distance(begin(v), it)
  4. 获取

演示:链接

我会把它作为一个答案发布,即使我把它放在评论中。

鉴于您对在矩阵中存储生长序列的描述,以下使用 std::is_sorted_until 的示例代码可用于简单的do-while循环。

#include <vector>
#include <algorithm>
bool fun(std::vector<int>& v)
{
    // our matrix
    std::vector<std::vector<int>> matrix;
    // initially point to beginning of vector
    auto startIter = v.begin();
    auto iter = startIter;
    do 
    {
        // return first item that is out of order
        iter = std::is_sorted_until(startIter, v.end());
        // save everything as a matrix row, 
        // starting from beginning up to the item that's out of order
        matrix.push_back({ startIter, iter });
        // set new starting position to the position of the 
        // item out-of-order
        if ( iter != v.end())
            startIter = iter;
    } while (iter != v.end());  // keep going until we reach the end
    return true;
}

现场示例

上面示例中的注释应该足以解释正在发生的事情。

关键是,每当你编写一个处理数据序列的循环时,总是认为可能有一种算法或一组 STL 算法函数使工作更容易。 在这种情况下,该算法std::is_sorted_until


您可以通过使用纯迭代器使上述内容更加通用:

#include <vector>
#include <algorithm>
template <typename Iter>
bool fun(Iter iter1, Iter iter2)
{
    // our matrix
    std::vector<std::vector<int>> matrix;
    // initially point to beginning of vector
    auto startIter = iter1;
    auto iter = startIter;
    do 
    {
        // return first item that is out of order
        iter = std::is_sorted_until(startIter, iter2);
        // save everything as a matrix row, 
        // starting from beginning up to the item that's out of order
        matrix.push_back({ startIter, iter });
        // set new starting position to the position of the 
        // item out-of-order
        if ( iter != iter2)
            startIter = iter;
    } while (iter != iter2);  // keep going until we reach the end
    return true;
}
int main()
{
    int arr [] = { 1,2,3,2,5,6,4,8,3 };
    fun(arr, std::end(arr));
}

现场示例