Contoh kode C ++ sebelum dan sesudah Rentang

Halo lagi. Terjemahan dari materi berikut disiapkan khusus untuk siswa kursus "Pengembang C ++" , kelas yang akan dimulai pada 27 Juni.



Perpustakaan Ranges diadopsi dalam C ++ 20 pada pertemuan komite standar di San Diego November lalu. Perpustakaan menyediakan komponen untuk memproses rentang nilai yang dirancang untuk menyederhanakan kode kami. Sayangnya, perpustakaan Ranges tidak terdokumentasi dengan baik, yang membuatnya lebih sulit untuk dipahami bagi mereka yang ingin menguasainya. Posting ini dimaksudkan untuk memberikan contoh kode yang ditulis menggunakan dan tanpa Ranges.

Implementasi perpustakaan Eric Niebler's Ranges tersedia di sini . Ia bekerja dengan Dentang 3.6.2 atau lebih baru, gcc 5.2 atau lebih baru, dan VC ++ 15.9 atau lebih baru. Contoh kode di bawah ini telah ditulis dan diuji dengan versi kompiler terbaru. Perlu dicatat bahwa contoh-contoh ini adalah implementasi yang tipikal dan tidak selalu merupakan satu-satunya solusi yang dapat Anda temukan.

Meskipun namespace standar untuk perpustakaan Ranges adalah std::ranges , dalam implementasi perpustakaan saat ini adalah ranges::v3 .

Alias ​​namespace berikut digunakan dalam contoh di bawah ini:

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

Juga, untuk penyederhanaan, kita akan merujuk ke objek, fungsi, dan lambda berikut:

 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 : Saya ingin mengucapkan terima kasih kepada Eric Nibler dan semua orang yang berkomentar di bawah ini, dengan saran untuk contoh kode ini. Saya memperbarui beberapa berdasarkan ulasan mereka.

Cetak semua elemen rentang:

Ke rentangSetelah rangs
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); 


Cetak semua elemen rentang dalam urutan terbalik:

Ke rentangSetelah rangs
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); }; 


Cetak hanya elemen genap dari rentang tersebut, tetapi dengan urutan terbalik:

Ke rentangSetelah rangs
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); }; 


Lewati dua elemen pertama rentang dan cetak hanya elemen genap dari tiga berikut:

Ke rentangSetelah rangs
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); }; 


Cetak angka dari 101 hingga 200:

Ke rentangSetelah rangs
C ++C ++
 for (int n = 101; n <= 200; ++n) { print_elem(n); } 
 for (auto n : rs::iota_view(101, 201)) { print_elem(n); } 


Cetak semua angka Romawi dari 101 hingga 200. Untuk mengonversi angka ke angka Romawi yang sesuai, gunakan fungsi to_roman() ditunjukkan di atas.

Ke rentangSetelah rangs
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); 


Cetak angka Romawi dari tiga angka terakhir yang dapat habis dibagi 7 pada kisaran [101, 200], dalam urutan terbalik.

Ke rentangSetelah rangs
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); } 


Buat rentang string yang berisi angka romawi dari tiga angka terakhir yang merupakan kelipatan 7 dalam kisaran [101, 200], dalam urutan terbalik.

Ke rentangSetelah rangs
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; 


Ubah rentang yang tidak disortir sehingga hanya mempertahankan nilai unik, tetapi dalam urutan terbalik.

Ke rentangSetelah rangs
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; 


Hapus dua nilai terkecil dan dua terbesar dari rentang dan biarkan sisanya diurutkan dalam kisaran kedua.

Ke rentangSetelah rangs
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); 


Gabungkan semua baris dalam rentang yang diberikan ke nilai tunggal.

Ke rentangSetelah rangs
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; 


Hitung jumlah kata (dipisahkan oleh spasi) dalam teks.

Ke rentangSetelah rangs
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(' ')); 


Apakah artikel itu membantu Anda? Tulis di komentar.

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


All Articles