kutuzzzov

Урок 7-2 Move итераторы

Jan 18th, 2023
489
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.36 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <string>
  4. #include <vector>
  5. #include <iterator>
  6. #include <iostream>
  7. #include <numeric>
  8.  
  9. using namespace std;
  10.  
  11. // Объявляем Sentence<Token> для произвольного типа Token
  12. // синонимом vector<Token>.
  13. // Благодаря этому в качестве возвращаемого значения
  14. // функции можно указать не малопонятный вектор векторов,
  15. // а вектор предложений — vector<Sentence<Token>>.
  16. template <typename Token>
  17. using Sentence = vector<Token>;
  18.  
  19. template <typename TokenForwardIt>
  20. TokenForwardIt FindSentenceEnd(TokenForwardIt tokens_begin, TokenForwardIt tokens_end) {
  21.     const TokenForwardIt before_sentence_end
  22.         = adjacent_find(tokens_begin, tokens_end, [](const auto& left_token, const auto& right_token) {
  23.               return left_token.IsEndSentencePunctuation() && !right_token.IsEndSentencePunctuation();
  24.           });
  25.     return before_sentence_end == tokens_end ? tokens_end : next(before_sentence_end);
  26. }
  27.  
  28. // Класс Token имеет метод bool IsEndSentencePunctuation() const
  29. template <typename Token>
  30. vector<Sentence<Token>> SplitIntoSentences(vector<Token> tokens) {
  31.     vector<Sentence<Token>> result;
  32.     auto it_start = tokens.begin();
  33.     auto it = tokens.begin();
  34.     auto it_end = tokens.end();
  35.    
  36.     while (it_start != it_end) {
  37.     auto it_token = FindSentenceEnd(it_start, it_end);
  38.         if (it == it_token) {
  39.             result.push_back({make_move_iterator(it_start), make_move_iterator(it_token)});
  40.             it_start = it;
  41.         }
  42.     ++it;
  43.     }
  44.     return result;
  45. }
  46.  
  47. struct TestToken {
  48.     string data;
  49.     bool is_end_sentence_punctuation = false;
  50.  
  51.     bool IsEndSentencePunctuation() const {
  52.         return is_end_sentence_punctuation;
  53.     }
  54.     bool operator==(const TestToken& other) const {
  55.         return data == other.data && is_end_sentence_punctuation == other.is_end_sentence_punctuation;
  56.     }
  57.    
  58.    // TestToken(const TestToken&) = delete;
  59.    // TestToken& operator=(const TestToken&) = delete;
  60.    
  61. };
  62.  
  63. ostream& operator<<(ostream& stream, const TestToken& token) {
  64.     return stream << token.data;
  65. }
  66.  
  67. // Тест содержит копирования объектов класса TestToken.
  68. // Для проверки отсутствия копирований в функции SplitIntoSentences
  69. // необходимо написать отдельный тест.
  70. void TestSplitting() {
  71.     assert(SplitIntoSentences(vector<TestToken>({{"Split"s}, {"into"s}, {"sentences"s}, {"!"s}}))
  72.            == vector<Sentence<TestToken>>({{{"Split"s}, {"into"s}, {"sentences"s}, {"!"s}}}));
  73.  
  74.     assert(SplitIntoSentences(vector<TestToken>({{"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}}))
  75.            == vector<Sentence<TestToken>>({{{"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}}}));
  76.  
  77.     assert(SplitIntoSentences(vector<TestToken>(
  78.                {{"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}, {"!"s, true}, {"Without"s}, {"copies"s}, {"."s, true}}))
  79.            == vector<Sentence<TestToken>>({
  80.                {{"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}, {"!"s, true}},
  81.                {{"Without"s}, {"copies"s}, {"."s, true}},
  82.            }));
  83. }
  84.  
  85. int main() {
  86.     TestSplitting();
  87. }
Add Comment
Please, Sign In to add comment