二元谓词的工作原理是什么?

时间:2017-09-14 11:35:54

标签: c++ merge stl

在下面的代码中,在二元谓词函数mycomparison中,为什么首先从L2(2.1)而不是L1(1.4)获得第一项?同样,第二个是从L1获得第一个项目。并且此行为是特定于此功能(合并)还是可以扩展到其他功能。我们可以假设容器的顺序,将决定传递给二元谓词函数的顺序吗?

#include <iostream>
#include <list>
bool mycomparison(double first, double second)
{
    std::cout <<"first "<< first << " " << "second "<< second << "\n"; 
    return (int (first) <  int (second) );
}

int main()
{
    std::list<double> L1, L2;
    L1.push_back(3.1); L1.push_back(2.2); L1.push_back(2.9);
    L2.push_back(3.7); L2.push_back(7.1); L2.push_back(1.4);
    L1.sort(); L2.sort();
    L1.merge(L2);

    std::cout << "L1 contains: ";
    for (std::list<double>::iterator it = L1.begin(); it != L1.end(); ++it)
        std::cout << *it << ",  ";
    std::cout << '\n'; 

    L2.push_back(2.1);
    L2.push_back(3.2);

    std::cout << "L2 contains: ";
    for (std::list<double>::iterator it = L2.begin(); it != L2.end(); ++it)
        std::cout << *it << ",  ";
    std::cout << '\n';

    L1.merge(L2, mycomparison);

    std::cout << "L1 contains: ";
    for (std::list<double>::iterator it = L1.begin(); it != L1.end(); ++it)
        std::cout << *it << ",  ";
    std::cout << '\n';
    return 0;
}

输出

L1 contains: 1.4,  2.2,  2.9,  3.1,  3.7,  7.1,  
L2 contains: 2.1,  3.2,  
first 2.1 second 1.4
first 2.1 second 2.2
first 2.1 second 2.9
first 2.1 second 3.1
first 3.2 second 3.1
first 3.2 second 3.7
first 3.2 second 7.1
L1 contains: 1.4,  2.2,  2.9,  2.1,  3.1,  3.7,  3.2,  7.1,  

这是一个使用二元谓词或比较的排序函数。但是,传递给函数的项目也是&#34;不是按顺序&#34;。在myfunction变量中,我将获得向量(71)中的第二项而不是第一项(32)。为什么呢?

#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction(int i, int j) { 
    std::cout << i << " " <<j<<"\n" ; 
    return (i<j); }

int main() {
    int myints[] = { 32,71,12,45 };
    std::vector<int> myvector(myints, myints + 4);               

    std::sort(myvector.begin(), myvector.end(), myfunction); 

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

输出

71 32
71 32
12 32
45 12
45 71
45 32
myvector contains: 12 32 45 71

1 个答案:

答案 0 :(得分:2)

Strict Weak Ordering中,例如您使用mycomparison函数定义的那个,两个对象可能不相等但“等效”。在您的情况下,由于mycomparison(2.2, 2.1)mycomparison(2.1, 2.2)都是假的,因此数字2.12.2在该排序中是等效的。

因此L1的最终顺序实际上是根据mycomparison排序排序的,因为2.22.92.1都被视为等效。此外,std::list::merge保证已在*this2.22.9)中的元素出现在从参数列表(2.1)移出的等效元素之前。你可以看到这种行为也得到了遵守。