4 votes

Suppression des doublons d'une liste d'ensembles

J'implémente le fameux problème des "sous-ensembles d'un ensemble". Je pense avoir obtenu une bonne solution fonctionnelle, mais elle contient des doublons. J'espérais que list.unique() s'occuperait de la situation, mais comme pour un ensemble l'opérateur == n'est pas défini, cela ne fonctionne pas. Un ensemble d'ensembles ne résout pas non plus la situation (j'utilise maintenant une liste d'ensembles).

Ayant une solution complète à 80%, je me rends compte qu'il existe un meilleur algorithme que celui que j'ai trouvé. Mais je me demande s'il existe un moyen astucieux de supprimer les doublons sans réécrire complètement l'algorithme ?

Voici mon code :

MAIN.CPP :

#include "random.hpp"

using namespace std;

int main(void) {

    subsets2();

    getchar();
    return 0;
}

Random.Cpp :

void getSubsets2(set<int> myset, list<set<int> > * ptr, int length) {

    if (length == 1) {
        ptr->push_back(myset);
    }

    else {
        set<int> second(myset);
        set<int>::iterator it;
        ptr->push_back(myset);

        it = myset.begin();
        myset.erase(it);
        it = second.begin();
        ++it;
        second.erase(it);

        getSubsets2(myset, ptr, length - 1);
        getSubsets2(second, ptr, length - 1);
    }
}

void subsets2(void) {
    const int N = 4;
    int myints[N] = {
        88, 33, 23, 22
    };
    set<int> myset(myints, myints + N);
    set<int> set2;

    list<set<int> > mylist;

    list<set<int> > * ptr;
    ptr = & mylist;

    list<set<int> > ::iterator it;
    set<int>::iterator it2;

    getSubsets2(myset, ptr, N);
    mylist.unique();

    for (it = mylist.begin(); it != mylist.end(); ++it) {
        set2 = * it;
        for (it2 = set2.begin(); it2 != set2.end(); ++it2) {
            cout << * it2 << " ";
        }
        cout << "\n";
    }

}

Sortie :

        22 23 33 88
        23 33 88
        33 88
        88
        33
        23 88
        88
        23
        22 33 88 
        33 88
        88
        33
        22 88
        88
        22

3voto

billz Points 28166

Unique() supprime toutes les consecutive les éléments en double du conteneur. Il faut donc d'abord trier mylist avant d'exécuter unique().

   mylist.sort();
   mylist.unique();

1voto

Yuushi Points 10656

C'est une autre façon de procéder, std::less<T> est défini pour tous les conteneurs standard. Par conséquent, nous pouvons définir quelque chose comme :

std::set<std::set<int>, std::less<std::set<int>>> set_of_sets;

Cela permettra de filtrer automatiquement les jeux en double. Un exemple complet :

#include <set>
#include <vector>
#include <iostream>
#include <functional>

int main()
{
    std::vector<std::vector<int>> x = {{1,2,3}, {1,2}, {1,2,3}, {4,5,6},
                                       {4,5}, {5,6}, {4,5,6}};
    std::set<std::set<int>, std::less<std::set<int>>> set_of_sets;

    for(auto it = x.begin(); it != x.end(); ++it) {
        std::set<int> s;
        s.insert(it->begin(), it->end());
        set_of_sets.insert(s);
    }

    for(auto it = set_of_sets.begin(); it != set_of_sets.end(); ++it) {
        std::cout << "{";
        for(auto it2 = it->begin(); it2 != it->end(); ++it2) {
            std::cout << *it2 << ", ";
        }
        std::cout << "}\n";
    }

    return 0;
}

1voto

perreal Points 47912

Utilisation d'une liste de chaînes pour stocker les résultats finaux :

    list<string> uniq_list;
    for (it = mylist.begin(); it != mylist.end(); ++it) {
        set2 = * it; 
        stringstream ss; 
        for (it2 = set2.begin(); it2 != set2.end(); ++it2) {
            ss << * it2 << " ";
        }
        uniq_list.push_back(ss.str());
    }   
    uniq_list.sort();
    uniq_list.unique();
    for (list<string>::iterator it=uniq_list.begin(); it != uniq_list.end(); it++){
      cout << *it << endl;
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X