set_difference并不总是返回正确的答案

时间:2019-12-11 11:42:09

标签: c++ algorithm sorting stl

我目前正在研究进化算法。我编写了一个程序来实现交叉功能,即在向量kA之间交换B元素。这是代码:

#include <algorithm>
#include <cstdio>
#include <ctime>
#include <iostream>
#include <iterator>
#include <random>
#include <set>
#include <vector>

using namespace std;

vector<int> reservoir_sampling(vector<int> input, int k)
{
    vector<int> output(k);
    int i;
    for (i = 0; i < k; i++)
    {
        output[i] = input[i];
    }
    srand(time(nullptr));
    while(i < input.size())
    {
        int j = rand() % (i+1);
        if (j < k)
        {
            output[j] = input[i];
        }
        i++;
    }
    return output;
}

template<typename T>
void vprintf(vector<T> V)
{
    for (T v : V)
    {
        cout << v << " ";
    }
    cout << endl;
}

void test()
{
    // crossover between A and B at k points
    vector<int> A = {0, 1, 2, 3, 4, 5};
    vector<int> B = {6, 7, 8, 9};
    printf("A: ");
    vprintf(A);
    printf("B: ");
    vprintf(B);
    int k = 2;
    vector<int> outers = reservoir_sampling(A, k);
    vector<int> inners = reservoir_sampling(B, k);
    printf("outers: ");
    vprintf(outers);
    printf("inners: ");
    vprintf(inners);
    // uS = A + inners
    vector<int> uS;
    set_union(A.begin(), A.end(), inners.begin(), inners.end(), inserter(uS, uS.end()));
    sort(uS.begin(), uS.end());
    printf("uS =  A + inners: ");
    vprintf(uS);
    // dS = uS - outers
    vector<int> dS;
    set_difference(uS.begin(), uS.end(), outers.begin(), outers.end(), inserter(dS, dS.end()));
    sort(dS.begin(), dS.end());
    printf("dS = uS - outers: ");
    vprintf(dS);
}

int main()
{
    test();
    return 0;
}

有时候,输出是正确的,例如:

A: 0 1 2 3 4 5
B: 6 7 8 9
outers: 3 4
inners: 9 7
uS =  A + inners: 0 1 2 3 4 5 7 9
dS = uS - outers: 0 1 2 5 7 9

有时,输出不正确,例如:

A: 0 1 2 3 4 5
B: 6 7 8 9
outers: 3 1
inners: 9 7
uS =  A + inners: 0 1 2 3 4 5 7 9
dS = uS - outers: 0 1 2 4 5 7 9

事实证明,set_union总是可以的,但set_difference却不能。我不知道我做错了什么。 SO的全能用户,请帮帮我!

1 个答案:

答案 0 :(得分:2)

您违反了std::set_unionstd::set_difference的先决条件:

  

构造一个从d_first开始的已排序的并集,该集合由存在于一个或两个已排序的范围[first1, last1)[first2, last2)中的元素集组成。

     

已排序范围[first1, last1)中找不到的元素从已排序范围复制到{{1 }}。

在一般情况下,[first2, last2)函数不会产生排序的向量。您的程序的行为是不确定的。

标准库提供std::sample function用于随机抽样。如果给它一对前向或随机访问迭代器,它将保留所选元素的相对顺序。

d_first