C++ C++;在向量中推回

C++ C++;在向量中推回,c++,stdvector,C++,Stdvector,我构建了一个递归函数,它读取一个向量作为输入,并返回一个新的向量,其中每两个连续的元素都被切换。例如,输入:123456和输出:214365。我不明白的是,当我以这种方式编写函数时: vector<int> reverse(vector<int> v) { if (v.size() < 2) return v; else { int pos1 = v.at(0); //= 1 int pos

我构建了一个递归函数,它读取一个向量作为输入,并返回一个新的向量,其中每两个连续的元素都被切换。例如,输入:
123456
和输出:
214365
。我不明白的是,当我以这种方式编写函数时:

vector<int> reverse(vector<int> v) {

    if (v.size() < 2)
        return v;
    else
    {
        int pos1 = v.at(0);  //= 1
        int pos2 = v.at(1);  //= 2

        v.erase(v.begin());  //v = 2 3 4 5 6
        v.erase(v.begin());  //v = 3 4 5 6

        vector<int> rev = reverse(v);

        rev.push_back(pos2);  //rev = 2
        rev.push_back(pos1);  //rev = 2 1

        return rev;
    }
}
main()函数如下所示:

int main() {

    vector<int> w;
    int zahl;

    cout << "Please give the vector or any letter to end the input: "<< endl;

    while (cin >> zahl)
    {
        w.push_back(zahl);
    }

    for (int elem : reverse(w))
    {
        cout << elem << ", ";
    }
    return 0;
}
intmain(){
向量w;
国际扎尔;
库特·扎尔)
{
w、 推回(zahl);
}
用于(内部元素:反向(w))
{
这是一个很容易解决的问题

代码的问题是递归步骤无法正确地将正确构造的子结果转换为稍大的子结果。 您希望执行以下操作:

// Correctly create the head of the result.
vector<int> rev = {pos2, pos1};

// Now you want to handle the tail, and assuming the output of reverse
// is correct for smaller lists, this would be achieved by appending
// the rest.
const auto sub = reverse(v);
rev.insert(rev.end(), sub.begin(), sub.end());
//正确创建结果的头部。
向量rev={pos2,pos1};
//现在,您需要处理尾部,并假设输出为反向
//对于较小的列表是正确的,这可以通过添加
//其余的。
const auto sub=反向(v);
版本插入(版本结束(),子版本开始(),子版本结束());
这确保了如果列表以
12
开头,它将变成一个带有
21
的列表,后面是正确处理的尾部


您的第二个代码工作正常,因为您正在反向处理序列,因此您的递归步骤实际上是正确的。

您得到的结果是不正确的,因为在最后一次调用函数时,您返回了一个空向量,然后在这个向量的后面推送最后一对倒转的数字,所以
6,5
,所以您执行了pr返回调用堆栈。 让我们看看您在每次通话(第一次通话、第二次通话、ecc)中都有哪些内容:

  • v=
    [1,2,3,4,5,6]
    ->递归调用
  • v=
    [3,4,5,6]
    ->递归调用
  • v=
    [5,6]
    ->递归调用
  • v=
    []
    ->返回空向量
  • rev=
    []
    ,按相反顺序向后推v的前两个元素,因此rev=
    [6,5]
    ->返回rev
  • rev=
    [6,5]
    ,按相反顺序向后推v的前两个元素,因此rev=
    [6,5,4,3]
    ->返回rev
  • rev=
    [6,5,4,3]
    ,按相反顺序向后推v的前两个元素,因此rev=
    [6,5,4,3,2,1]
  • 出于这个原因,您首先需要有一个前两个数字颠倒的向量,然后附加处理过的尾部,如上所述

    请注意,每次调用函数时都在构造向量的副本。可以创建反向副本,而无需修改作为参数提供的参数副本。我将使用迭代器,以便每次函数“看到”原始向量的较小部分,不接触它。以下是一个实现:

    vector<int> reverse(vector<int>::const_iterator begin, vector<int>::const_iterator end) {
    
        if (begin==end-1) //the vector has an odd number of elements, let's append the last element
            return vector<int>(1, *(end-1));
        else if(begin>=end) //the vector has en even number of elements
            return vector<int>();
        else
        {
            vector<int> pairWiseReversed({*(begin+1), *begin});
            vector<int> tail=reverse(begin+2, end);
            pairWiseReversed.insert(pairWiseReversed.end(), tail.begin(), tail.end());
            return pairWiseReversed;
        }
    }
    
    vector<int> buildReversed(const vector<int>& input){
        return reverse(input.begin(), input.end());
    }
    
    向量反转(向量::常量迭代器开始,向量::常量迭代器结束){
    如果(begin==end-1)//向量的元素数为奇数,那么让我们附加最后一个元素
    返回向量(1,*(end-1));
    else if(begin>=end)//向量的元素数为偶数
    返回向量();
    其他的
    {
    向量成对倒换({*(begin+1),*begin});
    矢量尾=反向(开始+2,结束);
    插入(pairwiserversed.end(),tail.begin(),tail.end());
    返回成对倒转;
    }
    }
    向量构建(常量向量和输入){
    返回反向(input.begin(),input.end());
    }
    
    这里有一个主要问题:

    int main() {
        vector<int> v{1,2,3,4,5,6};
        cout<<"Input vector"<<endl;
        for(auto n:v)
            cout<<n<<" ";
        cout<<endl;
    
        vector<int> res=buildReversed(v);
        cout<<"Output vector"<<endl;
        for(auto n:res)
            cout<<n<<" ";
        cout<<endl;
        return 0;
    }
    
    intmain(){
    向量v{1,2,3,4,5,6};
    库特
    
    int main() {
        vector<int> v{1,2,3,4,5,6};
        cout<<"Input vector"<<endl;
        for(auto n:v)
            cout<<n<<" ";
        cout<<endl;
    
        vector<int> res=buildReversed(v);
        cout<<"Output vector"<<endl;
        for(auto n:res)
            cout<<n<<" ";
        cout<<endl;
        return 0;
    }