STL通用算法: iter_swap,reverse,reverse_copy,advance算法

本文介绍了C++ STL中的基础算法iter_swap、reverse和advance的使用方法及其实现原理,展示了如何利用这些算法进行元素交换、容器倒序及迭代器定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习C语言时,当我们需要互换两个数的时候,我们会这么写,或者通过指针去写.

int temp = a;
a = b;
b = temp;

所以在STL中针对互换容器内的元素时,就有了iter_swap基础算法,就是用来互换两个指针所指向内容的方法.

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

int main()
{
    vector<int> s = {1,2,3,4,5};
    vector<int> temp = {10,9,8,7,6};


    iter_swap(s.begin(),--temp.end());//s: 6 2 3 4 5
                                      //temp: 10 9 8 7 1
    system("pause");
    return 0;
}

下面是iter_swap的实现:

template <typename T>
void myIter_swap(T left, T right)
{
    auto temp = *left;
    *left = *right;
    *right = temp;
}

当我们学会了iter_swap的用法之后,就可以用iter_swap来实现reverse倒序算法了.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> s = {1,2,3,4,5};
    //用来把容器内指定范围内的元素倒过来排,也相当于翻转.也可以用到rotate算法,这里不提.
    reverse(s.begin(), s.end());

    for (auto temp: s)
    {
        cout << temp<< " ";//输出 5 4 3 2 1.
    }
    cout << endl;

    system("pause");
    return 0;
}

实现reverse倒序算法.

template <typename T>
void myReverse(T first, T last)
{
    while (first < last)
    {
        iter_swap(first++, --last);
    }
}

reverse_copy同理:

template <typename T>
void my_Reserve_copy(T first, T last, T new_first)
{
    while (first != last)
    {
        //注意尾迭代器是取不到的,遵循了左闭右开原则!!
        *new_first++ = *--last;
    }
}

我们知道在string,vector这些一大块连续内存的数据容器用起来都是十分方便的,比如string重载了’+’运算符,可以更直观的对字符串进行操作,vector的迭代器也可以直接和数字相加减,获取想要的迭代器的位置,但对于list来说,就有些麻烦了,比如:

list<int> s = {1,3,5,7,9111315};
auto temp = s.begin();
//我们想要获取一个指向9的迭代器.
//有朋友说,那这样不就好了嘛,但这样其实是错误的,因为list没有重载'+'号运算符.
auto c = s.begin()+4;
//甚至有些朋友是这样做的:虽然结果是正确的,但有两个问题,第一个问题是比较麻烦,别人看起来也不方便,第二个问题是:不同的编译器给出的结果都是不同的,因为明确规定了:在一个表达式中,变量的值只能被改变一次,如果多次改变,那么其结果是未定义的.所以不要这么写.
auto c = ++++++++s.begin();

//接下来是重头戏啦!!!
//advance算法的使用.
list<int> s = {1,3,5,7,9111315};
auto temp = s.begin();
//advance算法并没有返回值,只是在原有迭代器的基础上,进行了移动.
advance(temp, 4);
cout << *temp << endl;  //输出结果为: 9.
//在现在的基础上:
advance(temp,-1);
cout << *temp << endl; //输出结果为: 7.

下面是advance的实现:

template <typename T>
void myAdvance(T &base, int len)
{
    if (len >= 0)
    {
        for (int i = 0; i < len; ++i)
        {
            base++;
        }
    }
    else
    {
        for (int i = len; i < 0; ++i)
        {
            base--;
        }
    }
}
Line 7: Char 9: ================================================================= ==22==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000000354 at pc 0x55de9091eda9 bp 0x7ffeb85c4260 sp 0x7ffeb85c4258 READ of size 4 at 0x502000000354 thread T0 #0 0x55de9091eda8 in swap<int> /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/move.h:222:13 #1 0x55de9091eda8 in iter_swap<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > > /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_algobase.h:185:7 #2 0x55de9091eda8 in void std::__reverse<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>>>, std::random_access_iterator_tag) /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_algo.h:1062:4 #3 0x55de9091ec00 in reverse<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > > /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_algo.h:1089:7 #4 0x55de9091ec00 in Solution::rotate(std::vector<int, std::allocator<int>>&, int) solution.cpp:7:9 #5 0x55de9091e4ad in __helper__ solution.cpp:7:18 #6 0x55de9091e4ad in main solution.cpp:7:30 #7 0x7f3b1408a1c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6) #8 0x7f3b1408a28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 6d64b17fbac799e68da7ebd9985ddf9b5cb375e6) #9 0x55de90847f44 in _start (solution+0xb2f44) 0x502000000354 is located 0 bytes after 4-byte region [0x502000000350,0x502000000354) allocated by thread T0 here: #0 0x55de9091bb6d in operator new(unsigned long) /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:86:3 #1 0x55de909381de i
最新发布
03-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值