问题
I want to traverse through the values of a vector in opposite direction. As you know the size of a vector is of size_t. When I use the following code:
for(size_t r=m.size()-1; r >= 0; r--)
{
x[r] = f[r];
for(size_t c = r+1; c < m.size(); c++)
{
x[r] -= m[r][c] * x[c];
}
}
I will go out of the range of the vector because the r will become 4294967295 after decrementing r = 0.
I am not changing the r's type because in my project, I am treating warnings as errors, so it should be size_t or I should cast it which is not interesting.
回答1:
If you actually want to use size_t
for indexing, the loop could be formulated as follows.
for(size_t r = m.size(); r > 0; r--)
{
x[r-1] = f[r-1];
for(size_t c = r; c < m.size(); c++)
{
x[r-1] -= m[r-1][c] * x[c];
}
}
Basically you would iterate from m.size()
to 1
and compensate by shifting inside the loop; but this solution might be a bit hard to follow. In this question, a proposed solution is to use a reverse_iterator
, which can be seen as a suitable abstraction of the index. The entire topic is coverd in more depth in this question.
回答2:
This is my favorite way:
std::size_t r = m.size();
while (r --> 0)
{
// access m[r]
}
回答3:
Well, you should avoid size_t
as much as possible, since it is an
unsigned type, and unsigned types aren't well behaved in C++, at least
when it comes to arithmetic. But regardless of the type, the usual
idiom I'd use for iterating in reverse (assuming for some reason I can't
just use reverse iterators, which would be the natural solution) would
be something like:
int r = m.size(); // but size_t r would work here too.
while ( r > 0 ) {
-- r;
// ...
}
Moving the decrementation to the top of the loop solves most of the problems, and is IMHO much clearer.
回答4:
Unsigned arithmetic is well-defined in C++, so I would just compare against the "overflow":
for (size_t r = m.size() - 1; r != -1; r--)
In the loop condition, the -1
is automatically converted to an unsigned with the correct value.
回答5:
Using Boost.Range:
for (auto r : boost::irange(std::size_t(0), m.size()) | boost::adaptors::reversed) {
x[r] = f[r];
for (auto c : boost::irange(r + 1, m.size())) {
x[r] -= m[r][c] * x[c];
}
}
回答6:
For anyone who is still searching for a method use the difference type
from the containers, only a slight modification is needed in the code, instead of using size_t r = m.size()-1
use the following
std::vector<T>::difference_type r = m.end()-m.begin()
or you can use
std::ptrdiff_t r = m.end()-m.begin()
and the loop will work
ptrdiff_t is just an alias that marks the distance between 2 iterators.
来源:https://stackoverflow.com/questions/27402237/traversing-a-vector-in-reverse-direction-with-size-t-values