我目前在向量中保持一个范围时遇到一些问题。
在下面的代码中,我试图检查正在检查的数字是否小于或等于数字
#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;
,但这意味着我无法比较该向量中的最后两个元素。
有人可以推荐这个问题的解决方案吗?
谢谢
答案 0 :(得分:2)
在这段代码中:
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
,则可以解决问题。
答案 1 :(得分:1)
以下是我编写此代码的方法:
auto prev = begin(v);
auto it = prev;
if(it == end(v))
return;
it ++;
for(; it != end(v); it++, prev++)
{
if(*prev <= *it)
{
//code
}
}
有一些好处:
它适用于多种类型的容器,包括list
和数组,例如int v[] = {10,20,30,40,50};
或array<int, 5>
迭代器只能转发,不一定是随机访问。
distance(begin(v), it)
演示:link
答案 2 :(得分: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;
}
答案 3 :(得分:0)
即使我将其放在评论中,我也会将此作为答案发布。
鉴于您在矩阵中存储增长序列的描述,使用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));
}