代码之家  ›  专栏  ›  技术社区  ›  user997112

在容器上双向迭代

  •  2
  • user997112  · 技术社区  · 7 年前

    有没有比下面的代码更好的方法,使用相同的迭代器在容器的任意方向上迭代?

    #include <iostream>
    #include <map>
    
    int main()
    {
        const bool descend = false;
    
        std::map<int, int> mapp;
        mapp[1] = 1;
        mapp[2] = 2;
        mapp[3] = 3;
        mapp[4] = 4;
    
        std::map<int, int>::iterator startIter = descend ? --(mapp.end()) : mapp.begin();
        std::map<int, int>::iterator endIter = descend ? --(mapp.begin()) : mapp.end();
    
        while (startIter != endIter)
        {
            std::cout << startIter->first << std::endl;
            descend ? --startIter : ++startIter;
        }
    }
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   Slava    7 年前

    您的代码在此语句中无效 --(mapp.begin()) 通向乌兰巴托。我会写一个薄薄的包装:

    template<class Iter, class F>
    void apply( Iter begin, Iter end, F f, bool forward )
    {
        while( begin != end ) 
            f( forward ? *begin++ : *--end );
    }
    

    live example

    或者只需将循环重写为:

    auto begin = mapp.begin();
    auto end = mapp.end();
    while ( begin != end)
    {
        const auto &p = forward ? *begin++ : *--end;
        std::cout << p.first << std::endl;
    }
    
        2
  •  2
  •   JeJo    7 年前

    有没有比下面的代码更好的方法来遍历容器 在两个方向上,使用相同的迭代器?

    是的 . 使用 std::map::reverse_iterator . 这将是一种比您发布的代码更好的方法,但这将不再使用相同的迭代器,这是您的需求之一。

    但是,这将比您编写的代码更不容易出错。除此之外,如果已经在C++中,你就不需要重新发明轮子了。

    See output here

    #include <iostream>
    #include <map>
    
    template<typename Iterator>
    void print(const Iterator Begin, const Iterator End)
    {
        for(Iterator iter = Begin; iter != End; ++iter)
           std::cout << iter->first << "\n";
    }
    
    int main()
    {
        const bool descend = true;
    
        std::map<int, int> mapp;
        mapp[1] = 1;
        mapp[2] = 2;
        mapp[3] = 3;
        mapp[4] = 4;
    
        descend ?
            print(mapp.crbegin(), mapp.crend()):
            print(mapp.cbegin(), mapp.cend());
        return 0;
    }
    

    图片来自 cppreference.com 将以图形方式解释它是如何工作的。 enter image description here

        3
  •  -1
  •   Shog9    7 年前

    编写自我文档化的代码,它就会变得简单。将循环分解为自己的函数,并使用适当的迭代器调用它。

    这就是为什么我们有“反向迭代器”,它们可以通过使用正常的正向语义来向后遍历容器。

    #include <iostream>
    #include <map>
    
    template<typename I>
    void printMapContainer(I begin, I end)
    {
        for (;begin != end; ++begin)
        {
            std::cout << begin->first << "\n";
        }
    }
    int main()
    {
        const bool descend = false;
    
        std::map<int, int> mapp;
        mapp[1] = 1;
        mapp[2] = 2;
        mapp[3] = 3;
        mapp[4] = 4;
    
        if (descend) {
            printMapContainer(mapp.rbegin(), mapp.rend());
        }
        else {
            printMapContainer(mapp.begin(), mapp.end());
        }
    }