Traversing a vector in reverse direction with size_t values

微笑、不失礼 提交于 2021-02-07 18:09:03

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!