使用 size_t 值反向遍历矢量

Traversing a vector in reverse direction with size_t values

本文关键字:遍历 size 使用      更新时间:2023-10-16

我想以相反的方向遍历向量的值。如您所知,向量的大小是size_t。当我使用以下代码时:

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];
    }
}

我将超出向量的范围,因为在递减 r = 0 后 r 将变得4294967295。

我没有更改 r 的类型,因为在我的项目中,我将警告视为错误,所以它应该是size_t的,或者我应该投射它,这并不有趣。

如果您真的想使用 size_t 进行索引,循环可以表述如下。

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];
    }
}

基本上,你会从m.size()迭代到1,并通过在循环内移动进行补偿;但这个解决方案可能有点难以遵循。在这个问题中,一个建议的解决方案是使用reverse_iterator,这可以看作是索引的合适抽象。这个问题更深入地涵盖了整个主题。

这是我

最喜欢的方式:

std::size_t r = m.size();
while (r --> 0)
{
    // access m[r]
}

好吧,您应该尽可能避免size_t,因为它是一个无符号类型,至少在C++中表现不佳说到算术。 但无论哪种类型,通常我会用来反向迭代的成语(假设由于某种原因我不能只需使用反向迭代器,这将是自然的解决方案)将像这样:

int r = m.size();     //  but size_t r would work here too.
while ( r > 0 ) {
    -- r;
    //  ...
}

将递减移到循环的顶部可以解决大部分问题问题,恕我直言,这要清楚得多。

无符号算术在C++中定义得很好,所以我只想与"溢出"进行比较:

for (size_t r = m.size() - 1; r != -1; r--)

在循环条件中,-1会自动转换为具有正确值的无符号。

使用 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];
    }
}

对于仍在搜索方法的任何人,请使用容器中的difference type,只需在代码中进行轻微修改,而不是使用以下size_t r = m.size()-1

std::vector<T>::difference_type r = m.end()-m.begin()

或者您可以使用

std::ptrdiff_t r = m.end()-m.begin()和循环将工作ptrdiff_t只是一个别名,用于标记 2 个迭代器之间的距离