Exemples de code C ++ avant et après les plages

Bonjour encore. La traduction du matériel suivant a été préparée spécialement pour les étudiants du cours "Développeur C ++" , dont les cours commenceront le 27 juin.



La bibliothèque Ranges a été adoptée en C ++ 20 lors d'une réunion du comité standard à San Diego en novembre dernier. La bibliothèque fournit des composants pour le traitement des plages de valeurs conçues pour simplifier notre code. Malheureusement, la bibliothèque Ranges n'est pas très bien documentée, ce qui la rend plus difficile à comprendre pour ceux qui souhaitent la maîtriser. Ce message est destiné à fournir des exemples de code écrit en utilisant et sans plages.

L'implémentation de la bibliothèque Ranges d'Eric Niebler est disponible ici . Il fonctionne avec Clang 3.6.2 ou version ultérieure, gcc 5.2 ou version ultérieure et VC ++ 15.9 ou version ultérieure. Les exemples de code ci-dessous ont été écrits et testés avec les dernières versions des compilateurs. Il convient de noter que ces exemples sont des implémentations typiques et ne sont pas nécessairement les seules solutions que vous pouvez trouver.

Bien que l'espace de noms standard pour la bibliothèque Ranges soit std::ranges , dans cette implémentation de bibliothèque actuelle, il s'agit de ranges::v3 .

Les alias d'espace de noms suivants sont utilisés dans les exemples ci-dessous:

 namespace rs = ranges::v3; namespace rv = ranges::v3::view; namespace ra = ranges::v3::action; 

Aussi, pour simplifier, nous ferons référence aux objets, fonctions et lambdas suivants:

 std::string to_roman(int value) { std::vector<std::pair<int, char const*>> roman { { 1000, "M" },{ 900, "CM" }, { 500, "D" },{ 400, "CD" }, { 100, "C" },{ 90, "XC" }, { 50, "L" },{ 40, "XL" }, { 10, "X" },{ 9, "IX" }, { 5, "V" },{ 4, "IV" }, { 1, "I" } }; std::string result; for (auto const & [d, r]: roman) { while (value >= d) { result += r; value -= d; } } return result; } std::vector<int> v{1,1,2,3,5,8,13,21,34}; auto print_elem = [](auto const e) {std::cout << e << '\n'; }; auto is_even = [](auto const i) {return i % 2 == 0; }; 

APDATE : Je voudrais remercier Eric Nibler et tous les autres qui ont commenté ci-dessous, avec des suggestions pour ces exemples de code. J'en ai mis à jour quelques-uns en fonction de leurs critiques.

Imprimez tous les éléments de la gamme:

Vers les gammesAprès les sonneries
C ++C ++
 std::for_each( std::cbegin(v), std::cend(v), print_elem); // or for(auto const i : v) { print_elem(i); }; 
 rs::for_each( std::cbegin(v), std::cend(v), print_elem); // or rs::for_each(std::as_const(v), print_elem); 


Imprimez tous les éléments de la gamme dans l'ordre inverse:

Vers les gammesAprès les sonneries
C ++C ++
 std::for_each( std::crbegin(v), std::crend(v), print_elem); 
 rs::for_each( std::crbegin(v), std::crend(v), print_elem); // or for (auto const i : v | rv::reverse) { print_elem(i); }; 


N'imprimez que les éléments pairs de la plage, mais dans l'ordre inverse:

Vers les gammesAprès les sonneries
C ++C ++
 std::for_each( std::crbegin(v), std::crend(v), [print_elem](auto const i) { if(i % 2 == 0) print_elem(i); }); 
 for (auto const i : v | rv::reverse | rv::filter(is_even)) { print_elem(i); }; 


Ignorez les deux premiers éléments de la gamme et imprimez uniquement les éléments pairs parmi les trois suivants:

Vers les gammesAprès les sonneries
C ++C ++
 auto it = std::cbegin(v); std::advance(it, 2); auto ix = 0; while (it != std::cend(v) && ix++ < 3) { if (is_even(*it)) print_elem(*it); it++; } 
 for (auto const i : v | rv::drop(2) | rv::take(3) | rv::filter(is_even)) { print_elem(i); }; 


Imprimer les nombres de 101 à 200:

Vers les gammesAprès les sonneries
C ++C ++
 for (int n = 101; n <= 200; ++n) { print_elem(n); } 
 for (auto n : rs::iota_view(101, 201)) { print_elem(n); } 


Imprimez tous les chiffres romains de 101 à 200. Pour convertir un nombre en nombre romain correspondant, utilisez la fonction to_roman() illustrée ci-dessus.

Vers les gammesAprès les sonneries
C ++C ++
 for (int i = 101; i <= 200; ++i) { print_elem(to_roman(i)); } 
 for (auto n : rs::iota_view(101, 201) | rv::transform(to_roman)) { print_elem(n); } // or rs::for_each(rv::iota(101, 201), print_element, to_roman); 


Imprimez les chiffres romains des trois derniers nombres divisibles par 7 dans la plage [101, 200], dans l'ordre inverse.

Vers les gammesAprès les sonneries
C ++C ++
 for (int n = 200, count=0; n >= 101 && count < 3; --n) { if (n % 7 == 0) { print_elem(to_roman(n)); count++; } } 
 for (auto n : rs::iota_view(101, 201) | rv::reverse | rv::filter([](auto v) { return v % 7 == 0; }) | rv::transform(to_roman) | rv::take(3)) { print_elem(n); } 


Créez une plage de chaînes contenant les chiffres romains des trois derniers nombres qui sont des multiples de 7 dans la plage [101, 200], dans l'ordre inverse.

Vers les gammesAprès les sonneries
C ++C ++
 std::vector<std::string> v; for (int n = 200, count = 0; n >= 101 && count < 3; --n) { if (n % 7 == 0) { v.push_back(to_roman(n)); count++; } } 
 auto v = rs::iota_view(101, 201) | rv::reverse | rv::filter([](auto v) {return v % 7 == 0; }) | rv::transform(to_roman) | rv::take(3) | rs::to_vector; 


Modifiez la plage non triée afin qu'elle ne conserve que des valeurs uniques, mais dans l'ordre inverse.

Vers les gammesAprès les sonneries
C ++C ++
 std::vector<int> v{ 21, 1, 3, 8, 13, 1, 5, 2 }; std::sort(std::begin(v), std::end(v)); v.erase( std::unique(std::begin(v), std::end(v)), std::end(v)); std::reverse(std::begin(v), std::end(v)); 
 std::vector<int> v{ 21, 1, 3, 8, 13, 1, 5, 2 }; v = std::move(v) | ra::sort | ra::unique | ra::reverse; 


Supprimez les deux plus petites et les deux plus grandes valeurs de la plage et laissez le reste ordonné dans la deuxième plage.

Vers les gammesAprès les sonneries
C ++C ++
 std::vector<int> v{ 21, 1, 3, 8, 13, 1, 5, 2 }; std::vector<int> v2 = v; std::sort(std::begin(v2), std::end(v2)); auto first = std::begin(v2); std::advance(first, 2); auto last = first; std::advance(last, std::size(v2) - 4); v2.erase(last, std::end(v2)); v2.erase(std::begin(v2), first); 
 std::vector<int> v{ 21, 1, 3, 8, 13, 1, 5, 2 }; auto v2 = v | rs::copy | ra::sort | ra::slice(2, rs::end - 2); 


Combinez toutes les lignes d'une plage donnée en une seule valeur.

Vers les gammesAprès les sonneries
C ++C ++
 std::vector<std::string> words { "Lorem", " ", "ipsum", " ", "dolor", " ", "sit", " ", "amet"}; std::string text; for (auto const & word : words) text += word; 
 std::vector<std::string> words { "Lorem", " ", "ipsum", " ", "dolor", " ", "sit", " ", "amet"}; std::string text = words | rs::move | ra::join; 


Comptez le nombre de mots (séparés par un espace) dans le texte.

Vers les gammesAprès les sonneries
C ++C ++
 auto text = "Lorem ipsum dolor sit amet"; std::istringstream iss(text); std::vector<std::string> words( std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>()); auto count = words.size(); // or size_t count = 0; std::vector<std::string> words; std::string token; std::istringstream tokenStream(text); while (std::getline(tokenStream, token, ' ')) { ++count; } 
 auto text = "Lorem ipsum dolor sit amet"; auto count = rs::distance( rv::c_str(text) | rv::split(' ')); 


L'article vous a-t-il été utile? Écrivez dans les commentaires.

Source: https://habr.com/ru/post/fr456452/


All Articles