web-dev-qa-db-fra.com

Moyen efficace de trouver des éléments uniques dans un vecteur comparé contre plusieurs vecteurs

J'essaie de trouver le nombre d'éléments uniques dans un vecteur comparé contre plusieurs vecteurs à l'aide de C++. Les vecteurs sont en ordre triés et peuvent être de taille 2 000 000.

Supposons que j'ai,

v1: 5, 8, 13, 16, 20
v2: 2, 4, 6, 8
v3: 20
v4: 1, 2, 3, 4, 5, 6, 7
v5: 1, 3, 5, 7, 11, 13, 15

Le nombre d'éléments uniques en V1 est 1 (c'est-à-dire numéro 16).

J'ai essayé deux approches.

  1. Vecteurs ajoutés v2, v3, v4 et v5 dans un vecteur de vecteur. Pour chaque élément de V1, vérifié si l'élément est présent dans l'un des autres vecteurs.

  2. Combiné tous les vecteurs V2, V3, V4 et V5 utilisent la fusion dans un seul vecteur et la comparé contre V1 pour trouver les éléments uniques.

Remarque: Sample_Vector = V1 et All_Vectors_Merry contient V2, V3, V4, V5

//Method 1
unsigned int compute_unique_elements_1(vector<unsigned int> sample_vector,vector<vector<unsigned int> > all_vectors_merged)
{
    unsigned int duplicate = 0;
    for (unsigned int i = 0; i < sample_vector.size(); i++)
    {
        for (unsigned int j = 0; j < all_vectors_merged.size(); j++)
        {
            if (std::find(all_vectors_merged.at(j).begin(), all_vectors_merged.at(j).end(), sample_vector.at(i)) != all_vectors_merged.at(j).end())
            {
                duplicate++;
            }
        }
    }
    return sample_vector.size()-duplicate;
}

// Method 2
unsigned int compute_unique_elements_2(vector<unsigned int> sample_vector, vector<unsigned int> all_vectors_merged)
{
    unsigned int unique = 0;
    unsigned int i = 0, j = 0;
    while (i < sample_vector.size() && j < all_vectors_merged.size())
    {
        if (sample_vector.at(i) > all_vectors_merged.at(j))
        {
            j++;
        }
        else if (sample_vector.at(i) < all_vectors_merged.at(j))
        {
            i++;
            unique ++;
        }
        else
        {
            i++;
            j++;
        }
    }
    if (i < sample_vector.size())
    {
        unique += sample_vector.size() - i;
    }
    return unique;
}

Sur ces deux techniques, je vois que la méthode 2 donne des résultats plus rapides.

1) Méthode 1: Y a-t-il un moyen plus efficace de trouver les éléments que d'exécuter STD :: Trouvez sur tous les vecteurs pour tous les éléments de V1.

2) Méthode 2: frais généraux supplémentaires dans la comparaison des vecteurs V2, V3, V4, V5 et les triches.

Comment puis-je faire cela de manière meilleure?

[modifier] Les vecteurs sont en ordre triés.

6
SyncMaster

Utilisez des tables de hachage. Les éléments sont la clé et le nombre d'occurrences sont les valeurs.

10
ddyer

Comme il est trié, vous pouvez utiliser standard std::set_difference Fonction:

unsigned int compute_uniqute_elements(vector<unsigned int> sample_vector, vector<unsigned int> merged_vectors)
{
    vector<unsigned int> difference;
    vector<unsigned int>::iterator it;
    it = std::set_difference(sample_vector.begin(), sample_vector.end(), it->begin(), it->end(), difference.begin());

    return std::distance(difference.begin(), it);
}
1
BenjaminB

On dirait que vos données sont des chaînes et vous avez utilisé des valeurs numériques pour illustrer plus facilement les aspects du problème, comme chaque vecteur étant trié, mais avoir beaucoup de vecteurs à itérer.

programmation dynamique peut fournir de grandes occasions d'économiser de grandes économies d'efficacité. En règle générale, la programmation dynamique exécute une partie de votre algorithme pour générer une solution partielle pouvant être réutilisée dans des itérations ultérieures pour gagner du temps. Il y a une Grande version du problème du vendeur itinérant Cela fait cela pour des économies de temps énormes (au compromis de la nécessité d'énormes quantités de mémoire).

Si vous connaissez des choses sur vos données, disons qu'il est limité aux valeurs entières entre 0 et 99, une approche simple serait de faire une table de 100 booléens, analyser les vecteurs une fois pour marquer la table pour montrer quels éléments sont présents, Comparez ensuite votre vecteur de test contre la table.

S'il s'agissait d'un algorithme de recherche et que l'entrée était une clé de plusieurs chaînes et que les données de vecteur multiples triées étaient des mots-clés à partir de documents, vous pouvez choisir de nombreuses méthodes pour collecter les chaînes uniques dans une représentation appropriée pour binaire = ou autre recherche . Le stockage nécessaire à cette structure de données d'assistance dépendra du nombre de chaînes uniques dans le jeu de données d'entrée. Il pourrait être surprenant pour les données même variées que le texte anglais, quelle quantité de chaînes uniques peuvent être trouvées dans deux millions de vecteurs de quelques centaines de mots chacun.

0
DeveloperDon