【问题标题】:Reversing an array (vector) using reverse_iterator使用 reverse_iterator 反转数组(向量)
【发布时间】:2019-06-17 16:53:24
【问题描述】:

我正在尝试通过 Edabit 挑战和测试“新”功能来提高我的 C++ 知识。当前的挑战希望我们编写一个函数来反转数组。 例子:

reverse([1, 2, 3, 4]) ➞ [4, 3, 2, 1]

reverse([9, 9, 2, 3, 4]) ➞ [4, 3, 2, 9, 9]

reverse([]) ➞ []

我尝试使用 reverse_iterator 执行此操作,但结果有些奇怪。

std::vector<int> reverse(std::vector<int> arr) {
    std::vector<int> out;
    for(std::vector<int>::reverse_iterator i = arr.rbegin(); i != arr.rend(); ++i)
    {
        out.push_back(arr[*i]);
    }
    return out;
}

我得到的结果如下:

FAILED: Expected: equal to [ 4, 3, 2, 1 ]
Actual: [ 0, 4, 3, 2 ]

首先它似乎只是一次,o 我用 rbegin() 加了 1 并如下所示:

for(std::vector<int>::reverse_iterator i = arr.rbegin() + 1; i != arr.rend() + 1; ++i)

第一个测试似乎通过了,但接下来的测试似乎还差得很远:

FAILED: Expected: equal to [ 7, 6, 5 ]
Actual: [ 33, 0, 5 ]

我试图了解这个反向迭代器是如何工作的,所以请提供一个解决方案和一些清晰的解释,为什么第一个测试通过添加 1 以及为什么第二个没有通过。

【问题讨论】:

  • 你可以简单地使用return std::vector&lt;int&gt;(arr.rbegin(), arr.rend());的1行解决方案

标签: c++ vector iterator c++17


【解决方案1】:

试试:

for(std::vector<int>::reverse_iterator i = arr.rbegin(); i != arr.rend(); ++i)
{
    out.push_back(*i);
}

迭代器已经为您提供了一个值,而不是向量的索引。

【讨论】:

  • 谢谢,成功了!所以第一次通过加 1 的测试只是巧合?
  • 是的,就是这样。
【解决方案2】:

下标运算符中的表达式

out.push_back(arr[*i]);
              ^^^^^^^   

没有意义。

你是说

out.push_back( *i );

但是在任何情况下,函数都可以像这样更好地编写来创建一个新的反向向量

#include <iostream>
#include <vector>
#include <iterator>


std::vector<int> reverse( const std::vector<int> &v ) 
{
    std::vector<int> out;
    out.reserve( v.size() );

    for ( auto first = std::rbegin( v ), last = std::rend( v ); first != last; ++first )
    {
        out.push_back( *first );
    }

    return out;
}

int main() 
{
    std::vector<int> v = { 4, 3, 2, 1 };

    for ( const auto &item : v ) std::cout << item << ' ';
    std::cout << '\n';

    auto reversed_v = reverse( v );

    for ( const auto &item : reversed_v ) std::cout << item << ' ';
    std::cout << '\n';

    return 0;
}

程序输出是

4 3 2 1 
1 2 3 4

或者像这样将向量反转到位

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>


void reverse( std::vector<int> &v ) 
{
    if ( not v.empty() )
    {
        for ( auto first = std::rbegin( v ), last = std::rend( v ); first < --last; ++first )
        {
            std::iter_swap( first, last );
        }
    }       
}

int main() 
{
    std::vector<int> v = { 4, 3, 2, 1 };

    for ( const auto &item : v ) std::cout << item << ' ';
    std::cout << '\n';

    reverse( v );

    for ( const auto &item : v ) std::cout << item << ' ';
    std::cout << '\n';

    return 0;
}

程序输出同上图

4 3 2 1 
1 2 3 4

或者,您可以使用相应的标准算法std::reverse_copystd::reverse

【讨论】:

  • @Aconcagua 它是运算符的保留替代表示!。
  • 我知道...就像or 可以代替||bitand 代替&amp;。这真是太不寻常了——实际上以前从未见过它们真正被使用过——不要把它当作批评:)。
【解决方案3】:

尽量选择标准库中的算法而不是手工制作的循环,因为:
1) 它们更具表现力;
2) 它们可能更有效率。

std::reverse(std::begin(arr), std::end(arr));

只需包含“算法”标头即可使用 std::reverse。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多