首页 > 解决方案 > 以某种算法从容器到二元谓词函数的参数流(发送参数对的方式)

问题描述

当我们希望算法根据我们自己对容器的要求运行时。然后我们创建自己的二进制谓词函数,我的代码包含bool twice(int e1,int e2){ return e1*2 == e2}在下面的代码列表L ={30,50,15,10,20,80,90}中,我使用过adjacent_find(L.begin(),L.end(),twice)算法来找到第一个是第二个两倍的整数对。在这里我无法理解参数的传递是如何发生的?(30,50) 是否发送到二进制谓词?如果是,那么发送的下一对参数是什么?是 (30,15) 然后 (30,10)---(30,90),或者(50,15) then (15,10)---(80,90),算法如何决定参数发送的流程?它们是什么?算法是否一遇到就停止执行其各自的任务二进制谓词的返回值为“真”?谁能解释我如何在容器元素和二进制谓词之间传递参数?

#include <iostream>
#include <algorithm>
#include <list>

bool twice(int e1,int e2)
{
    return e1 * 2 == e2;
}
int main()
{
    std::list<int> L ={30,50,15,10,20,80,90};
    std::list<int>::iterator i;

    i = std::adjacent_find(L.begin(),L.end(),twice);
    if(i==L.end())
        std::cout<<"There are not two adjacent elements where the second is twice the first.\n";
    else
        std::cout<<"Two adjacent elements where the second is twice the first are:"<<*(i++)<<" & "<<*(i);

    return 0;
}

标签: c++stlargumentsundefined-behaviordefinition

解决方案


正如算法的名称所暗示的那样,考虑了相邻的元素。对于您的示例中的列表

{ 30, 50, 15, 10, 20, 80, 90 }

相邻的元素是

( 30, 50 ), ( 50, 15 ), ( 15, 10 ), ( 10, 20 ), ( 20, 80 ), ( 80, 90 )

一旦找到满足二元谓词的第一个相邻元素对,算法就会停止执行并返回指向该对的第一个元素的迭代器。

考虑到这个声明

std::cout<<"Two adjacent elements where the second is twice the first are:"<<*(i++)<<" & "<<*(i);

导致未定义的行为,因为在这些表达式的计算*(i++)*(i).

要了解算法的工作原理,自己编写它很有用。

例如

#include <iostream>
#include <list>
#include <iterator>

template <typename ForwardIterator, typename BinaryPredicate>
ForwardIterator adjacent_find( ForwardIterator first, ForwardIterator last, BinaryPredicate binary_predicate )
{
    auto next = first;

    if ( first != last && ++next != last )
    {
        while ( next != last && not binary_predicate ( *first, *next ) )
        {
            ++first;
            ++next;
        }            
    }

    return next == last ? next : first;
}

int main()
{
        std::list<int> lst ={ 30, 50, 15, 10, 20, 80, 90 };
        auto twice = []( const auto &e1, const auto &e2 )
        {
            return 2 * e1 == e2;
        };

        auto it = ::adjacent_find( std::begin( lst ), std::end( lst ), twice );

        if ( it == std::end( lst ) )
        {
            std::cout << "There are not two adjacent elements where the second is twice the first.\n";
        }            
        else
        {
            std::cout << "Two adjacent elements where the second is twice the first are: "
                      << *it << " & " << *std::next( it ) << '\n';
        }                      
}

程序输出为

Two adjacent elements where the second is twice the first are: 10 & 20

推荐阅读