zoukankan      html  css  js  c++  java
  • STL之迭代器(iterator)

    1 头文件

    所有容器有含有其各自的迭代器型别(iterator types),所以当你使用一般的容器迭代器时,并不需要含入专门的头文件。不过有几种特别的迭代器,例如逆向迭代器,被定义于<iterator>中。

    2 迭代器类型

    迭代器共分为五种,分别为: Input iterator、Output iterator、Forward iterator、Bidirectional iterator、Random access iterator。

    2.1 Input(输入)迭代器

    只能一次一个向前读取元素,按此顺序一个个传回元素值。表2.1列出了Input迭代器的各种操作行为。Input迭代器只能读取元素一次,如果你复制Input迭代器,并使原Input迭代器与新产生的副本都向前读取,可能会遍历到不同的值。纯粹Input迭代器的一个典型例子就是“从标准输入装置(通常为键盘)读取数据”的迭代器。

    表达式                      功能表述

    *iter                  读取实际元素

    iter->member           读取实际元素的成员(如果有的话)

    ++iter                 向前步进(传回新位置)

    iter++                 向前步进(传回旧位置)

    iter1 == iter2         判断两个迭代器是否相同

    iter1 != iter2         判断两个迭代器是否不相等

    TYPE(iter)             复制迭代器(copy 构造函数)                                                                  

    2.2 Output(输出)迭代器

    Output迭代器和Input迭代器相反,其作用是将元素值一个个写入。表2.2列出Output迭代器的有效操作。operator*只有在赋值语句的左手边才有效。Output迭代器无需比较(comparison)操作。你无法检验Output迭代器是否有效,或“写入动作”是否成功。你唯一可以做的就是写入、写入、再写入。

    表达式                  功能表述

    *iter = value      将元素写入到迭代器所指位置

    ++iter             向前步进(传回新位置)

    iter++             向前步进(传回旧位置)

    TYPE(iter)         复制迭代器(copy 构造函数)                                                                  

    2.3 Forward(前向)迭代器

    Forward迭代器是Input迭代器与Output迭代器的结合,具有Input迭代器的全部功能和Output迭代器的大部分功能。表2.3总结了Forward迭代器的所有操作。Forward迭代器能多次指向同一群集中的同一元素,并能多次处理同一元素。

    表达式                 功能表述

    *iter               存取实际元素

    iter->member        存取实际元素的成员

    ++iter              向前步进(传回新位置)

    iter++              向前步进(传回旧位置)

    iter1 == iter2      判断两个迭代器是否相同

    iter1 != iter2      判断两个迭代器是否不相等

    TYPE()              产生迭代器(default构造函数)

    TYPE(iter)          复制迭代器(copy构造函数)

    iter1 == iter2      复制                                                              

    2.4 Bidirectional(双向)迭代器

    Bidirectional(双向)迭代器在Forward迭代器的基础上增加了回头遍历的能力。换言之,它支持递减操作符,用以一步一步的后退操作。

    2.5 Random Access(随机存取)迭代器

    Random Access迭代器在Bidirectional迭代器的基础上再增加随机存取能力。因此它必须提供“迭代器算数运算”(和一般指针“指针算术运算”相当)。也就是说,它能加减某个偏移量、能处理距离(differences)问题,并运用诸如<和>的相互关系操作符进行比较。以下对象和型别支持Random Access迭代器:

    • 可随机存取的容器(vector, deque)

    • strings(字符串,string,wstring)

    • 一般array(指针)

    3 迭代器相关辅助函数

    3.1 advance() 令迭代器前进

    3.2 distance() 处理迭代器之间的距离

    3.3 iter_swap() 交换两个迭代器所指内容

    4  迭代器配接器

    4.1 Reverse(逆向迭代器)

    逆向迭代器重新定义递增运算和递减运算,使其行为正好倒置。成员函数rbegin()和rend()各传回一个Reverse迭代器,和begin()和end()类似,共同定义一个半开区间。用正向迭代器可以直接构造一个逆向迭代器,但是构造之后会出现“错位”现象。原因在逆向迭代器要保证半开区间不会越界,可调用逆向迭代器的base()函数,保证转换值的正确性(迭代器移了一位)。

    4.2 Insert(安插型)迭代器

    Insert迭代器,也称为inserters,用来将“赋值新值”操作转换为“安插新值”操作。通过这种迭代器,算法可以执行安插(insert)行为而非覆盖(overwrite)行为。所有Insert迭代器都隶属于Output迭代器类型。所以它只提供赋值(assign)新值的能力。表4.2.1列出Insert迭代器的所有操作函数。

    表达式            功能表述

    *iter           无实际操作(传回iter)

    iter = value    安插value

    ++iter          无实际操作(传回iter)

    iter++          无实际操作(传回iter)

                                                                 

    C++标准程序库提供三种Insert迭代器:back inserters, front inserters, general inserters。它们的区别在于插入位置。事实上它们各自调用所属容器中不同的成员函数。所以Insert迭代器初始化时要清楚知道自己所属的容器是哪一种。表4.2.2列出Insert迭代器的种类。

         名称                     Class                 其所调用的函数             生成函数

    Back   inserter     back_inserter_iterator         push_back(value)        back_inserter(cont)

    Front inserter      front_insert_iterator          push_front(value)       front_inserter(cont)

    General inserter    insert_iterator                insert(pos, value)       inserter(cont, pos)

    4.3 Stream(流)迭代器

    Stream迭代器是一种迭代器配接器,通过它,你可以把stream当成算法的原点和终点。更明确的说,一个istream迭代器可以用来从input stream中读元素,而一个ostream迭代器可以用来对output stream写入元素。

    Stream迭代器的一种特殊形式是所谓的stream缓冲区迭代器,用来对stream缓冲区进行直接读取和写入操作。

    Ostream迭代器

    ostream迭代器 可以被赋予的值写入output stream中。下表列出ostream迭代器的各项操作

     

             算式                               功能表述

    ostream_iterator<T>(ostream)          为ostream产生一个ostream迭代器

    ostream_iterator<T>(ostream, delim)   为ostream产生一个ostream迭代器,各元素间以delim为分隔符(请注意,delim的型别是const char*)

    *iter                                 无实际操作(传回iter)

    iter = value                          将value写到ostream,像这样:ostream<<value。其后再输出一个delim(分隔符;如有定义的话)

    ++iter                                无实际操作(传回iter)

    iter++                                 无实际操作(传回iter)

    Istream迭代器

    istream迭代器是ostream迭代器的拍档,用来从input stream读取元素。透过istream迭代器,算法可以从stream中直接读取数据。istream迭代器的各项操作。

            算式                                功能表述

    istream_iterator<T>()                 产生一个end-of-stream迭代器

    istream_iterator<T>(istream)          为istream产生的一个迭代器(可能立即去读第一个元素)

    *iter                                 传回先前读取的值(如果构造函数并未立刻读取第一个元素值,则本式执行读取任务)

    iter->member                          传回先前读取的元素的成员(如果有的话)

    ++iter                                读取下一个元素,并传回其位置

    iter++                                读取下一个元素,并传回迭代器指向前一个元素

    iter1 == iter2                        检查iter1和iter2是否相等

    iter1 != iter2                        检查iter1和iter2是否不相等

    5.下面列举了些例子说明各个容器的用法:

    1、vector
    #include <iostream>
    #include <vector>
    
    int main()
    {
        std::vector<char> charVector;
    
        int x;
        for (x=0; x<10; ++x)
            charVector.push_back(65 + x);
    
        int size = charVector.size();
        for (x=0; x<size; ++x)
        {
            std::vector<char>::iterator start =
                charVector.begin();
            charVector.erase(start);
            std::vector<char>::iterator iter;
            for (iter = charVector.begin(); 
                    iter != charVector.end(); iter++)
            {
                std::cout << *iter;
            }
            std::cout << std::endl;
        }
    
        return 0;
    }
    2、deque
    #include <iostream>
    #include <deque>
    
    int main()
    {
        std::deque<char> charDeque;
        int x;
        for (x=0; x<10; ++x)
            charDeque.push_front(65 + x);
    
        int size = charDeque.size();
        for (x=0; x<size; ++x)
        {
            std::deque<char>::iterator start =
                charDeque.begin();
            charDeque.erase(start);
            std::deque<char>::iterator iter;
            for (iter = charDeque.begin(); 
                    iter != charDeque.end(); iter++)
            {
                std::cout << *iter;
            }
            std::cout << std::endl;
        }
    
        return 0;
    }
    3、list
    #include <iostream>
    #include <list>
    
    int main()
    {
        // Create and populate the list.
        int x;
        std::list<char> charList;
        for (x=0; x<10; ++x)
            charList.push_front(65 + x);
    
        // Display contents of list.
        std::cout << "Original list: ";
        std::list<char>::iterator iter;
        for (iter = charList.begin(); 
                iter != charList.end(); iter++)
        {
            std::cout << *iter;
            //char ch = *iter;
            //std::cout << ch;
        }
        std::cout << std::endl;
        
        // Insert five Xs into the list.
        std::list<char>::iterator start = charList.begin();
        charList.insert(++start, 5, 'X');
    
        // Display the result.
        std::cout << "Resultant list: ";
        for (iter = charList.begin(); 
        iter != charList.end(); iter++)
        {
            std::cout << *iter;
            //char ch = *iter;
            //std::cout << ch;
        }
        
        return 0;
    }
    4set
    #include <iostream>
    #include <set>
    
    int main()
    {
        // Create the set object.
        std::set<char> charSet;
    
        // Populate the set with values.
        charSet.insert('E');
        charSet.insert('D');
        charSet.insert('C');
        charSet.insert('B');
        charSet.insert('A');
    
        // Display the contents of the set.
        std::cout << "Contents of set: " << std::endl;
        std::set<char>::iterator iter;
        for (iter = charSet.begin(); iter != charSet.end(); iter++)
            std::cout << *iter << std::endl;
        std::cout << std::endl;
    
        // Find the D.
        iter = charSet.find('D');
        if (iter == charSet.end())
            std::cout << "Element not found.";
        else
            std::cout << "Element found: " << *iter;
    
        return 0;
    }
    5、multiset
    #include <iostream>
    #include <set>
    
    int main()
    {
        // Create the first set object.
        std::multiset<char> charMultiset1;
    
        // Populate the multiset with values.
        charMultiset1.insert('E');
        charMultiset1.insert('D');
        charMultiset1.insert('C');
        charMultiset1.insert('B');
        charMultiset1.insert('A');
        charMultiset1.insert('B');
        charMultiset1.insert('D');
    
        // Display the contents of the first multiset.
        std::cout << "Contents of first multiset: " << std::endl;
        std::multiset<char>::iterator iter;
        for (iter = charMultiset1.begin();
                iter != charMultiset1.end(); iter++)
            std::cout << *iter << std::endl;
        std::cout << std::endl;
    
        // Create the second multiset object.
        std::multiset<char> charMultiset2;
    
        // Populate the multiset with values.
        charMultiset2.insert('J');
        charMultiset2.insert('I');
        charMultiset2.insert('H');
        charMultiset2.insert('G');
        charMultiset2.insert('F');
        charMultiset2.insert('G');
        charMultiset2.insert('I');
        
        // Display the contents of the second multiset.
        std::cout << "Contents of second multiset: "
            << std::endl;
        for (iter = charMultiset2.begin();
        iter != charMultiset2.end(); iter++)
            std::cout << *iter << std::endl;
        std::cout << std::endl;
        
        // Compare the sets.
        if (charMultiset1 == charMultiset2)
            std::cout << "set1 == set2";
        else if (charMultiset1 < charMultiset2)
            std::cout << "set1 < set2";
        else if (charMultiset1 > charMultiset2)
            std::cout << "set1 > set2";
        
        return 0;
    }
    6、map
    #include <iostream>
    #include <map>
    
    typedef std::map<int, char> MYMAP;
    
    int main()
    {
        // Create the first map object.
        MYMAP charMap1;
    
        // Populate the first map with values.
        charMap1[1] = 'A';
        charMap1[4] = 'D';
        charMap1[2] = 'B';
        charMap1[5] = 'E';
        charMap1[3] = 'C';
    
        // Display the contents of the first map.
        std::cout << "Contents of first map: " << std::endl;
        MYMAP::iterator iter;
        for (iter = charMap1.begin();
                iter != charMap1.end(); iter++)
        {
            std::cout << (*iter).first << " --> ";
            std::cout << (*iter).second << std::endl;
        }
        std::cout << std::endl;
    
        // Create the second map object.
        MYMAP charMap2;
    
        // Populate the first map with values.
        charMap2[1] = 'F';
        charMap2[4] = 'I';
        charMap2[2] = 'G';
        charMap2[5] = 'J';
        charMap2[3] = 'H';
    
        // Display the contents of the second map.
        std::cout << "Contents of second map: " << std::endl;
        for (iter = charMap2.begin();
                iter != charMap2.end(); iter++)
        {
            std::cout << (*iter).first << " --> ";
            std::cout << (*iter).second << std::endl;
        }
        std::cout << std::endl;
    
        // Compare the maps.
        if (charMap1 == charMap2)
            std::cout << "map1 == map2";
        else if (charMap1 < charMap2)
            std::cout << "map1 < map2";
        else if (charMap1 > charMap2)
            std::cout << "map1 > map2";
        
        return 0;
    }
    7、multimap
    #include <iostream>
    #include <map>
    
    typedef std::multimap<int, char> MYMAP;
    
    int main()
    {
        // Create the first multimap object.
        MYMAP charMultimap;
    
        // Populate the multimap with values.
        charMultimap.insert(MYMAP::value_type(1,'A'));
        charMultimap.insert(MYMAP::value_type(4,'C'));
        charMultimap.insert(MYMAP::value_type(2,'B'));
        charMultimap.insert(MYMAP::value_type(7,'E'));
        charMultimap.insert(MYMAP::value_type(5,'D'));
        charMultimap.insert(MYMAP::value_type(3,'B'));
        charMultimap.insert(MYMAP::value_type(6,'D'));
    
        // Display the contents of the first multimap.
        std::cout << "Contents of first multimap: " << std::endl;
        MYMAP::iterator iter;
        for (iter = charMultimap.begin();
                iter != charMultimap.end(); iter++)
        {
            std::cout << (*iter).first << " --> ";
            std::cout << (*iter).second << std::endl;
        }
        std::cout << std::endl;
    
        // Create the second multimap object.
        MYMAP charMultimap2;
    
        // Populate the second multimap with values.
        charMultimap2.insert(MYMAP::value_type(1,'C'));
        charMultimap2.insert(MYMAP::value_type(4,'F'));
        charMultimap2.insert(MYMAP::value_type(2,'D'));
        charMultimap2.insert(MYMAP::value_type(7,'E'));
        charMultimap2.insert(MYMAP::value_type(5,'F'));
        charMultimap2.insert(MYMAP::value_type(3,'E'));
        charMultimap2.insert(MYMAP::value_type(6,'G'));
    
        // Display the contents of the second multimap.
        std::cout << "Contents of second multimap: " << std::endl;
        for (iter = charMultimap2.begin();
                iter != charMultimap2.end(); iter++)
        {
            std::cout << (*iter).first << " --> ";
            std::cout << (*iter).second << std::endl;
        }
        std::cout << std::endl;
    
        // Compare the multimaps.
        if (charMultimap == charMultimap2)
            std::cout << "multimap1 == multimap2";
        else if (charMultimap < charMultimap2)
            std::cout << "multimap1 < multimap2";
        else if (charMultimap > charMultimap2)
            std::cout << "multimap1 > multimap2";
        
        return 0;
    }
    8、stack
    #include <iostream>
    #include <list>
    #include <stack>
    
    int main()
    {
        std::stack<int, std::list<int> > intStack;
    
        int x;
        std::cout << "Values pushed onto stack:"
                  << std::endl;
        for (x=1; x<11; ++x)
        {
            intStack.push(x*100);
            std::cout << x*100 << std::endl;
        }
    
        std::cout << "Values popped from stack:"
                  << std::endl;
        int size = intStack.size();
        for (x=0; x<size; ++x)
        {
            std::cout << intStack.top() << std::endl;
            intStack.pop();
        }
    
        return 0;
    }
    9、queue
    #include <iostream>
    #include <list>
    #include <queue>
    
    int main()
    {
        std::queue<int, std::list<int> > intQueue;
    
        int x;
        std::cout << "Values pushed onto queue:"
                  << std::endl;
        for (x=1; x<11; ++x)
        {
            intQueue.push(x*100);
            std::cout << x*100 << std::endl;
        }
    
        std::cout << "Values removed from queue:"
                  << std::endl;
        int size = intQueue.size();
        for (x=0; x<size; ++x)
        {
            std::cout << intQueue.front() << std::endl;
            intQueue.pop();
        }
    
        return 0;
    }
    10、priority_queue
    #include <iostream>
    #include <list>
    #include <queue>
    
    int main()
    {
        std::priority_queue<int, std::vector<int>,std::greater<int> > intPQueue;
        int x;
        intPQueue.push(400);
        intPQueue.push(100);
        intPQueue.push(500);
        intPQueue.push(300);
        intPQueue.push(200);
    
        std::cout << "Values removed from priority queue:"
                  << std::endl;
        int size = intPQueue.size();
        for (x=0; x<size; ++x)
        {
            std::cout << intPQueue.top() << std::endl;
            intPQueue.pop();
        }
    
        return 0;
    }
  • 相关阅读:
    iOS开发时,在Xcode中添加多个Targets进行版本控制
    如何给苹果公司发邮件?
    快快快!27个提升效率的iOS开源库推荐
    史上最全的常用iOS的第三方框架
    Ajax提交与传统表单提交的区别说明
    js原生ajax请求get post笔记
    查看iOS Crash logs
    如何提高iOS开发能力
    iOS 常用的#define合集
    Xcode编译错误和警告汇总
  • 原文地址:https://www.cnblogs.com/qunews/p/3761405.html
Copyright © 2011-2022 走看看