【问题标题】:Compare two consecutive elements in std::list比较 std::list 中的两个连续元素
【发布时间】:2010-09-20 15:34:50
【问题描述】:

我想在遍历列表时比较 std::list 中的两个连续元素。当我的迭代器位于元素 i 时,访问元素 i+1 的正确方法是什么? 谢谢 科比

【问题讨论】:

  • 如果可能,您可能希望将问题标题更改为“如何比较 std::list 中的两个连续元素?”。我会自己做,但没有声誉;-)

标签: c++ list iterator compare


【解决方案1】:

STL 提供了相邻查找() 算法,可用于查找两个连续相等的元素。还有一个带有自定义谓词的版本。

这些是原型:

template <class ForwardIterator>
   ForwardIterator adjacent_find ( ForwardIterator first, ForwardIterator last );

template <class ForwardIterator, class BinaryPredicate>
   ForwardIterator adjacent_find ( ForwardIterator first, ForwardIterator last,
                                   BinaryPredicate pred );

【讨论】:

  • 你的答案是我希望我自己写的;我希望 OP 接受你的回答。好东西! +1(我会 +5,但网站不允许这样做)
【解决方案2】:
for (list<int>::iterator it = test.begin(); it!=test.end(); it++) {
        cout<<*it<<":\t";
        list<int>::iterator copy = it;
        for( list<int>::iterator it2 =  ++copy; it2!=test.end();it2++){
            cout<<*it2<<"\t";
        }
        cout<<endl;
    }

【讨论】:

    【解决方案3】:

    Boost 有一个名为 next 的实用程序(及其相反的 prior)用于此目的。

    *itr == *next(itr)
    

    编辑:但是,如果我们回过头来看看森林,真正的问题是,为什么要自定义编写您的adjacent_find 函数? (我建议接受 Nicola Bonelli 的回答。)这是 STL 的一部分,如果您的代码不使用 Boost,则不需要使用 Boost(感谢评论者指出这一点)。

    【讨论】:

    • 网站上几乎每个 C++ 问题都有完全不同的“如果你有 Boost”和“如果你限制在标准 C++”答案,这很有趣。几乎就像它们是不同的语言一样......
    • 我一直在想同样的事情:)
    • 就像不同的语言!对我来说,Boost 是让 C++ 值得使用的原因。 :-P 不使用 Boost 就像在编写 Scheme 代码时不使用 SRFI。 :-P
    • C++11 现在包括 std::nextstd::prev,在这种情况下不需要 boost。
    【解决方案4】:

    最简单的方法是保存两个迭代器(因为无论如何你都必须停在倒数第二个)。

    std::list<int>::const_iterator second = list.begin(),
                                   end = list.end();
    
    if ( second != end ) // Treat empty list
        for(std::list<int>::const_iterator first = second++; // Post-increment 
            second != end; 
            ++first, ++second)
        {
            //...
        }
    

    注意first 是用secondpost-incrementation 初始化的,所以循环开始时firstlist.begin(),第二个是list.begin()+1

    Chris Jester-Young points out 那个 boost 有 nextprior 函数,虽然我不熟悉这些函数(因为我的罪)实现它们是微不足道的(特别是考虑到 list 有双向迭代器)。

    template <class Iterator>
    Iterator next(Iterator i) // Call by value, original is not changed
    { 
        return ++i;
    }
    // Implementing prior is left as an exercise to the reader ;o) 
    

    我的感觉是,使用 next 并不能解决这个问题以及维护两个迭代器,因为您必须记住在每次使用时确保 next(i) 不等于 end()


    编辑:

    • 由于Luc Touraille 的评论,修复了列表为空时的错误。
    • 添加对next 的引用以及我认为它不适合此用例的原因。

    【讨论】:

    • 糟糕,写完 next 的实现后,我发现它与 Chris 在 hi post 中包含的链接中的完全相同。
    • 啊,简单明了的解决方案的力量! :-P 我仍然认为相邻查找是最简单的解决方案,但是是的。
    【解决方案5】:

    List 是一个可逆容器,所以它的迭代器是双向迭代器,它是 Forward Iterator 的一个模型,我很确定这意味着你可以做到这一点(或者类似的东西,如果你对打破循环中间等):

    if (!l.empty()) {
        for (list<T>::const_iterator i = l.begin();;) {
            const T &a = *i;
            ++i;
            if (i == l.end()) break;
            do_comparison(a, *i);
        }
    }
    

    你不能用输入迭代器来做到这一点,因为只要你有一个迭代器,这些值就“存在”。但是你可以使用前向迭代器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-16
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多