Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <cassert>
- #include <string>
- #include <vector>
- using namespace std;
- // Объявляем Sentence<Token> для произвольного типа Token
- // синонимом vector<Token>.
- // Благодаря этому в качестве возвращаемого значения
- // функции можно указать не малопонятный вектор векторов,
- // а вектор предложений — vector<Sentence<Token>>.
- template <typename Token>
- using Sentence = vector<Token>;
- template <typename TokenForwardIt>
- TokenForwardIt FindSentenceEnd(TokenForwardIt tokens_begin, TokenForwardIt tokens_end) {
- const TokenForwardIt before_sentence_end
- = adjacent_find(tokens_begin, tokens_end, [](const auto& left_token, const auto& right_token) {
- return left_token.IsEndSentencePunctuation() && !right_token.IsEndSentencePunctuation();
- });
- return before_sentence_end == tokens_end ? tokens_end : next(before_sentence_end);
- }
- // Класс Token имеет метод bool IsEndSentencePunctuation() const
- template <typename Token>
- vector<Sentence<Token>> SplitIntoSentences(vector<Token> tokens) {
- // Напишите реализацию функции, не копируя объекты типа Token
- vector<Sentence<Token>> libr;
- //size_t tokens_size = tokens.size();
- auto it_start = tokens.begin();
- while (it_start <= tokens.end()) {
- Sentence<Token> sentence; //создаем предложение, которое будем заполнять
- //узнаем, на какой позиции находится наш знак препинания
- auto it_sent_end = FindSentenceEnd(it_start, tokens.end());
- auto dist_to_stop = distance(tokens.begin(), it_sent_end);
- //Резервируем память для кол-ва элементов до первого пунктуационного знака
- sentence.reserve(dist_to_stop);
- //Заполняем предложение, перемещая из tokens
- for (auto it = it_start; it <= it_sent_end; ++it) {
- //*it = move(tokens.at(count++));
- sentence.push_back(move(*it));
- }
- //Добавляем предложение в словарь
- libr.push_back(move(sentence));
- //Удаляем предложение, чтобы потом создать его снова
- //sentence.clear();
- //delete sentence;
- //it_start = tokens.at(++dist_to_stop);
- advance(it_start, dist_to_stop++);
- }
- return libr;
- }
- struct TestToken {
- string data;
- bool is_end_sentence_punctuation = false;
- bool IsEndSentencePunctuation() const {
- return is_end_sentence_punctuation;
- }
- bool operator==(const TestToken& other) const {
- return data == other.data && is_end_sentence_punctuation == other.is_end_sentence_punctuation;
- }
- };
- ostream& operator<<(ostream& stream, const TestToken& token) {
- return stream << token.data;
- }
- // Тест содержит копирования объектов класса TestToken.
- // Для проверки отсутствия копирований в функции SplitIntoSentences
- // необходимо написать отдельный тест.
- void TestSplitting() {
- assert(SplitIntoSentences(vector<TestToken>({ {"Split"s}, {"into"s}, {"sentences"s}, {"!"s} }))
- == vector<Sentence<TestToken>>({ {{"Split"s}, {"into"s}, {"sentences"s}, {"!"s}} }));
- assert(SplitIntoSentences(vector<TestToken>({ {"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true} }))
- == vector<Sentence<TestToken>>({ {{"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}} }));
- assert(SplitIntoSentences(vector<TestToken>(
- { {"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}, {"!"s, true}, {"Without"s}, {"copies"s}, {"."s, true} }))
- == vector<Sentence<TestToken>>({
- {{"Split"s}, {"into"s}, {"sentences"s}, {"!"s, true}, {"!"s, true}},
- {{"Without"s}, {"copies"s}, {"."s, true}},
- }));
- }
- int main() {
- TestSplitting();
- }
Advertisement