web-dev-qa-db-fra.com

Que fait std :: includes?

De la norme,std::includes:

Renvoie: true si [first2, last2) Est vide ou si chaque élément de la plage [first2, last2) Est contenu dans la plage [first1, last1). Renvoie false sinon.

Remarque: comme c'est sous [alg.set.operations] , les plages doivent être triées

Prenant cela littéralement, si nous laissons R1=[first1, last1) Et R2=[first2, last2), Ceci évalue:

∀a∈R2 a∈R1

Cependant, ce n'est pas ce qui est réellement évalué. Pour R1={1} Et R2={1,1,1}, std::includes(R1, R2) renvoie faux:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> a({1});
    std::vector<int> b({1,1,1});

    // Outputs 'false'
    std::cout << std::boolalpha
        << std::includes(a.begin(), a.end(), b.begin(), b.end()) << '\n';
}

en direct sur Wandbox

C'est surprenant. Je l'ai vérifié avec libstdc ++ et libc ++, mais il me semble peu probable que ce soit un bogue dans l'implémentation de la bibliothèque standard, étant donné qu'il fait partie de la bibliothèque d'algorithmes. Si ce n'est pas l'algorithme que std::includes Est censé exécuter, qu'est-ce que c'est?

31
Justin

J'ai posté ceci dans le slack cpplang, et Casey Carter a répond :

La description de l'algorithme dans la norme est défectueuse. L'intention est de déterminer [si] chaque élément de l'aiguille apparaît dans l'ordre dans la botte de foin.

[L'algorithme qu'il exécute est:] "Renvoie vrai si l'intersection des séquences triées R1 et R2 est égale à R2"

Ou, si nous nous assurons que nous sommes certains de la signification de sous-séquence :

Renvoie: vrai si et seulement si [first2, last2) est une sous-séquence de [first1, last1)

lien vers le message de Casey Carter

30
Justin

Je pense que vous essayez de vérifier si a inclut b dans votre exemple, a ne comprend pas b mais b le fait inclure a. Si vous échangez b et a, cela retournera vrai, puisque a est inclus dans b.

J'espère que je ne manque pas quelque chose d'évident.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> a({1});
    std::vector<int> b({1,1,1});

    // Outputs 'true'
    std::cout << std::boolalpha
        << std::includes(b.begin(), b.end(), a.begin(), a.end()) << '\n';
}

Ce que j'ai compris en jouant avec l'algorithme, c'est que lorsque vous tapez includes(R2, R1) il vérifie si R2 Possède R1 En tant que sous-groupe, si oui retourne true sinon renvoie false. De plus, s'il n'est pas commandé, une erreur se produit: sequence not ordered.

3