C++ 使用 iter_swap 改变向量的顺序

Posted

技术标签:

【中文标题】C++ 使用 iter_swap 改变向量的顺序【英文标题】:C++ changing order of vector using iter_swap 【发布时间】:2017-10-07 17:26:23 【问题描述】:

我将一个包含 20 个项目的向量传递给下面的函数。我的目标是更改向量中项目的顺序。如果列表包含项目 1 2 3 4,我希望最终结果为 4 3 2 1。基本上将第一项与最后一项进行切换,将第二项与倒数第二项进行切换。

template<typename T>
void changePosition(std::vector<T>& list)

    std::cout << "Swapping \n";
    for (int i = 0; i < list.size(); i++)
    
        std::iter_swap(list.begin() + i, list.end() - i);
    

    std::cout << "Swapped \n";

我最终得到了错误:

c++ 向量迭代器不可解引用

有什么想法吗?我还没有找到任何可以实现我想要实现的样本。

std::reverse 确实可以使用,我正在处理的任务需要我使用 iter_swap。

【问题讨论】:

你不想交换迭代器,你想停止对迭代器所代表的元素的引用。如*it。再说一次,你不需要自己写这个,看看@Soren的答案。 仅供参考,当i==0list.end() - i 仅等同于list.end() 时,这不是您可以交换的有效元素。此外,如果您一直迭代到list.size(),您最终将反转向量两次;到循环结束时,你会发现你什么也没做! @MohamadAliBaydoun 始终参考文档:std::iter_swap() 交换迭代器引用的项目,而不是迭代器本身。 @frslm 你应该这样回答。 @Dúthomhas 我应该!但看起来其他人已经这样做了 【参考方案1】:

list.end() 指向向量的最后一个元素。因此,在循环的第一次迭代中,list.end() - i 将指向末尾,并且不能取消引用(或传递给 iter_swap)。

您应该改用list.end() - i - 1,以便它从最后一个元素开始。

但是一旦你解决了这个问题,你就会遇到另一个问题:你的代码将每个元素交换了两次,所以什么都不会改变。你应该停在向量的中间来解决这个问题。

当然,反转向量的最佳方法是使用标准函数std::reverse,而不是重新发明***。

【讨论】:

我明白了。这是我正在做的一项学校作业,需要我使用 iter_swap。【参考方案2】:

也许你应该只使用std::reverse

【讨论】:

【参考方案3】:

我设法解决了以下问题:

template<typename T>
void changePosition(std::vector<T>& list)

    std::cout << "Swapping \n";
    typedef std::vector<T>::iterator iterator;
    iterator first = list.begin();
    iterator last = list.end();

    while ((first != last) && (first != --last))
    
        std::iter_swap(first, last);
        ++first;
    

    std::cout << "Swapped \n";

我怀疑这是处理事情的最佳方式,但它完成了工作。 std::reverse 确实应该被其他试图反转向量的人使用。

我求助于 iter_swap 的唯一原因是因为我正在处理的任务需要它。

【讨论】:

【参考方案4】:

您可以使用 iter_swap 。事实上 std::reverse 也使用了 iter_swap

#include<vector>
#include<iostream>

template<class BidirIt>
void reverseVector(BidirIt first, BidirIt last)

    while ((first != last) && (first != --last)) 
        std::iter_swap(first++, last);
    


int main()

    std::vector<int> vec1,2,3,4;
    for(auto v:vec)
    
        std::cout<<v<<" ";
    
    std::cout<<"After reverting"<<"\n";
    reverseVector(vec.begin(),vec.end());
    for(auto v:vec)
    
        std::cout<<v<<" ";
    


输出

1 2 3 4 After reverting
4 3 2 1 Program ended with exit code: 0

【讨论】:

以上是关于C++ 使用 iter_swap 改变向量的顺序的主要内容,如果未能解决你的问题,请参考以下文章

使 C++ 模拟类同时使用 2D 和 3D 向量

c++ vector(向量)使用方法详解(顺序访问vector的多种方式)

C++ 删除存在于另一个向量中的向量项,同时保留顺序

c++ - 按特定顺序排列向量元素

在 C++ 中删除向量中的第一个最小数字(并保持顺序)

c++ 引用向量的问题?