通过引用传递向量使迭代算法以不同的方式运行

Posted

技术标签:

【中文标题】通过引用传递向量使迭代算法以不同的方式运行【英文标题】:Passing vector by reference makes iterative algorithm run differently 【发布时间】:2018-11-10 18:00:03 【问题描述】:

这个让我很困惑。我正在用 C++ 实现荷兰国旗问题。我最初忘记通过引用传递我的数组,但在每一步都显示数组,这帮助我得出结论,我的算法运行良好。为了解决向量最终没有被分区的微小错误,我将函数定义更改为传递向量作为参考,但不知何故产生了错误。

我以前从未遇到过这样的事情。代码不是递归的,因此当函数运行时,它是在向量的副本上运行还是在实际的向量上运行都无关紧要。

代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>

using namespace std;

void optArr(vector<int> arr)
    for(auto i: arr)
        cout<<setw(3)<<i<<" ";
    
    cout<<endl;


void _partition(vector<int> arr, int lo, int hi, int &i, int &k)  //Vector passed by value
    i=lo-1, k=hi+1;
    int ptr=lo, pivot=arr[hi];
    while(ptr<k)
        optArr(arr);
        cout<<"i: "<<i<<" ptr: "<<ptr<<" k: "<<k<<endl;
        if(arr[ptr]<pivot)
            swap(arr[++i],arr[ptr++]);
        else if(arr[ptr] == arr[pivot])
            ptr++;
        else
            swap(arr[--k],arr[ptr]);
        
    




int main()
    vector<int> arr = 57,22,85,17,11,04,17,93,1,17,25,17;
    int i,k;
    _partition(arr, 0, arr.size()-1, i, k);
    optArr(arr);
    cout<<"i: "<<i<<" ptr: "<<0<<" k: "<<k<<endl;

    return 0;

以及vector传值时的输出:

 57  22  85  17  11   4  17  93   1  17  25  17
i: -1 ptr: 0 k: 12
 17  22  85  17  11   4  17  93   1  17  25  57
i: -1 ptr: 0 k: 11
 17  22  85  17  11   4  17  93   1  17  25  57
i: -1 ptr: 1 k: 11
 17  25  85  17  11   4  17  93   1  17  22  57
i: -1 ptr: 1 k: 10
 17  17  85  17  11   4  17  93   1  25  22  57
i: -1 ptr: 1 k: 9
 17  17  85  17  11   4  17  93   1  25  22  57
i: -1 ptr: 2 k: 9
 17  17   1  17  11   4  17  93  85  25  22  57
i: -1 ptr: 2 k: 8
  1  17  17  17  11   4  17  93  85  25  22  57
i: 0 ptr: 3 k: 8
  1  17  17  17  11   4  17  93  85  25  22  57
i: 0 ptr: 4 k: 8
  1  11  17  17  17   4  17  93  85  25  22  57
i: 1 ptr: 5 k: 8
  1  11   4  17  17  17  17  93  85  25  22  57
i: 2 ptr: 6 k: 8
  1  11   4  17  17  17  17  93  85  25  22  57
i: 2 ptr: 7 k: 8
 57  22  85  17  11   4  17  93   1  17  25  17
i: 2 ptr: 0 k: 7

可以看到输出是正确的,一直到最后一个,是通过main函数调用的。当我看到这个时,我决定通过将_partition签名修改为:void _partition(vector&lt;int&gt; &amp;arr, int lo, int hi, int &amp;i, int &amp;k)

这产生了以下输出:

 57  22  85  17  11   4  17  93   1  17  25  17
i: -1 ptr: 0 k: 12
 17  22  85  17  11   4  17  93   1  17  25  57
i: -1 ptr: 0 k: 11
 25  22  85  17  11   4  17  93   1  17  17  57
i: -1 ptr: 0 k: 10
 17  22  85  17  11   4  17  93   1  25  17  57
i: -1 ptr: 0 k: 9
  1  22  85  17  11   4  17  93  17  25  17  57
i: -1 ptr: 0 k: 8
  1  22  85  17  11   4  17  93  17  25  17  57
i: 0 ptr: 1 k: 8
  1  93  85  17  11   4  17  22  17  25  17  57
i: 0 ptr: 1 k: 7
  1  17  85  17  11   4  93  22  17  25  17  57
i: 0 ptr: 1 k: 6
  1   4  85  17  11  17  93  22  17  25  17  57
i: 0 ptr: 1 k: 5
  1   4  85  17  11  17  93  22  17  25  17  57
i: 1 ptr: 2 k: 5
  1   4  11  17  85  17  93  22  17  25  17  57
i: 1 ptr: 2 k: 4
  1   4  11  17  85  17  93  22  17  25  17  57
i: 2 ptr: 3 k: 4
  1   4  11  17  85  17  93  22  17  25  17  57
i: 2 ptr: 0 k: 3

如您所见,这从输出的第三行开始就表现异常。对于这样一个含糊不清的问题,我深表歉意,但我不知道还有什么方法可以为这样一个不寻常的问题寻找解决方案。

【问题讨论】:

【参考方案1】:

在您的示例中,pivot == 17arr[pivot] 通过访问越界索引表现出未定义的行为。

【讨论】:

哇,我不知道我怎么错过了这么琐碎的事情。谢谢!

以上是关于通过引用传递向量使迭代算法以不同的方式运行的主要内容,如果未能解决你的问题,请参考以下文章

通过引用递归传递对象? JAVA

通过引用传递 - 左值和向量

通过引用传递向量内联

使对象不通过引用传递

C ++将向量传递给函数:引用与指针,哪个是首选? [复制]

通过引用传递向量的 typedef 向量