【问题标题】:Vector slicing in C++ in recursion递归中的 C++ 中的向量切片
【发布时间】:2020-12-14 20:02:16
【问题描述】:

这是一个使用python反向打印列表的简单函数。

def print_list(lst):
    if not lst:
        return
    print_list(lst[1:])  # How to achieve this slicing in C++ vector without any global, static variable.
    print(lst[0], end=" ")

我必须在不修改函数原型的情况下用 C++ 重写这个函数,而且我不想使用静态/全局索引变量。

C++ 函数原型和伪代码。

void print_rev(vector<int> &vec) {
    if(it reaches vector end)
        return;
    print_rev(vec[1:])
    print(vector elements during stack unwinding phase)
} 

如何像python函数一样对向量进行切片?

【问题讨论】:

  • 如果您必须保留该签名,则您要求在每次递归调用中制作向量的本地副本。在 c++20 中,您可以使用std::span。这样会很高效,而且语法也很简单。
  • Python 不是 C++。您使用 C++ 范例和习语解决了 C++ 问题,却忘记了 python 的存在。这适用于任何语言——您不会使用另一种语言作为模型以一种语言编写代码。
  • “重写而不修改函数签名”并不意味着你必须用递归来实现它。只需使用反向迭代器就可以完成这项工作。不相关,但是当函数显然不应该修改向量时,使用非常量引用参数定义此函数通常被认为是 C++ 中的不良风格。

标签: python c++ list recursion vector


【解决方案1】:

就我个人而言,我不会使用递归来执行此操作,而是使用反向迭代器,就像@r-sahu 给出的答案一样。但是,如果您真的想使用递归来执行此操作,则可以使用另一个带有迭代器的 print_rev() 重载。这样可以避免每次调用 print_rev() 时都必须创建一个新的临时向量:

#include <vector>
#include <iostream>

using Iter = std::vector<int>::iterator;

void print_rev(Iter start, Iter end)
{
    if (start == end)
        return;
    print_rev(std::next(start), end);
    std::cout << *start;
}

void print_rev(std::vector<int> &vec) {
    print_rev(vec.begin(), vec.end());
}

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

输出:

54321

这是demo

【讨论】:

    【解决方案2】:

    我必须在不修改函数原型的情况下用 C++ 重写这个函数,而且我不想使用静态/全局索引变量。

    如果函数的唯一目的是反向编写,可以使用std::vector::reverse_iterator。您不需要在递归调用中修改输入对象或创建临时对象。

    void print_rev(vector<int> &vec)
    {
        for ( auto iter = vec.rbegin(); iter != vec.rend(); ++iter )
        {
            print(*iter);
        }
    } 
    

    【讨论】:

      猜你喜欢
      • 2020-03-14
      • 1970-01-01
      • 2018-11-06
      • 2020-07-09
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多