desu
desu

Reputation: 455

C++ 11 set strange behaviour

Here's my code

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>

using namespace std;

struct comparator{
    bool operator()(const string& a, const string& b) const
    {
        if(a.length()>b.length()){
            return false;
        }
        else if(a.length()==b.length()){
            return (a<b);
        }
        else{
            return true;
        }
    }
};

void gen_combinations(string& tmp, set<string>& combs)
{
    for (int i=0; i<=tmp.length(); i++)
    {
        for(int k=i; k<=tmp.length(); k++)
        {
            combs.insert(tmp.substr(i, k-i+1));
        }
    }
}

int main()
{
    vector<string> words;
    set<string> combinations;
    set<string> forWord;
    set<string, comparator> result;
    string temp;
    vector<set<string>> container;
    int n;
    cin >> n;
    if(n!=1){
    for(int i = 0; i < n; i++){
        cin >> temp;
        words.push_back(temp);
        gen_combinations(temp, forWord);
        container.push_back(forWord);
        forWord.clear();
    }
    auto difference = [](set<string>& a, set<string>& b, set<string, comparator>& res){
        set_difference(a.begin(), a.end(), b.begin(), b.end(), inserter(res, res.end()));
    };
    for (int i=0; i<n; i++)
    {
        for(int g=0;g<n;g++){
            if(g!=i){
                combinations.insert(container[g].begin(), container[g].end());
            }
        }
        difference(container[i], combinations, result);
        if(result.begin()==result.end()){
            cout << "?";
        }
        else
        {
            cout << *result.begin();
        }
        cout << endl;
        result.clear();
        forWord.clear();
        combinations.clear();
    }
    }
    else
    {
        cin >> temp;
        for(int i=0;i<temp.length();i++){
            result.insert(temp.substr(i,1));
        }
        cout << *result.begin();
    }
    return 0;
}

I'm using that to define set<string, comparator> var1; and some more sets. After filling that sets I'm trying to use set_difference() and here's some output

variable1

a b e r ar be ea bea ear bear 

variable2

a b d e r ar be ea rd ard bea ear bear eard beard

variable1-variable2

bea ear bear

where var1 and var2 are sets and var1-var2 are set_difference() So why does that code acts so strange?(the difference between sets should be empty set)

P.S. If I'm not using comparator everything works good.

Upvotes: 3

Views: 65

Answers (1)

Jarod42
Jarod42

Reputation: 217145

With

std::set<string, comparator> var1 = // ...
std::set<string, comparator> var2 = // ...

you should use std::set_difference overload with comparer (and the comparer should be the same used for var1, var2 orders):

std::set_difference(var1.begin(), var1.end(),
                    var2.begin(), var2.end(),
                    inserter(res, res.end()),
                    comparator{});

Upvotes: 2

Related Questions