From 1d6e1df13b1b27bcf7144e03137b9a4f6acbcdcd Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Fri, 1 Apr 2016 20:45:40 +0200 Subject: Store spaces alongside tokens instead of as separate nodes --- src/line_accumulator.cc | 57 ++++++++++++++++++++++++------------------------- src/line_accumulator.h | 15 ++++++------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/line_accumulator.cc b/src/line_accumulator.cc index cf25c0c..b2facab 100644 --- a/src/line_accumulator.cc +++ b/src/line_accumulator.cc @@ -1,65 +1,64 @@ #include "line_accumulator.h" #include +#include LineAccumulator::LineAccumulator(const std::size_t max_length): max_length_{max_length}, random_{}, length_{0}, - tokens_{}, - spaces_{} { } + tokens_{} { } LineAccumulator::~LineAccumulator() { this->discharge(false); } void LineAccumulator::operator()(const std::string& word) { - if ( ( this->length_ + word.length() + 1 ) > this->max_length_ ) { - this->pop_trailing_token(); + if ( ( this->length_ + word.length() ) > this->max_length_ ) { this->discharge(true); } - this->add_token(word); - this->add_space(); -} + this->tokens_.emplace_back(word, 0); + this->length_ += word.length(); -void LineAccumulator::add_token(const std::string& token) { - this->length_ += token.length(); - this->tokens_.emplace_back(token); + if ( this->length_ < this->max_length_ ) { + this->tokens_.back().second += 1; + this->length_ += 1; + } } -void LineAccumulator::add_space() { - this->add_token(" "); - this->spaces_.emplace_back(this->tokens_.size() - 1); -} +void LineAccumulator::discharge(const bool full) { + if ( full ) { + this->length_ -= this->tokens_.back().second; + this->tokens_.back().second = 0; -void LineAccumulator::increase_space_at(const std::size_t index) { - this->tokens_.at(this->spaces_[index]).append(" "); - ++this->length_; -} + const std::size_t missing = this->max_length_ - this->length_; + const std::size_t base = missing / (this->tokens_.size()-1); -void LineAccumulator::pop_trailing_token() { - this->length_ -= this->tokens_.back().length(); - this->tokens_.pop_back(); - this->spaces_.pop_back(); -} + std::for_each( + this->tokens_.begin(), + this->tokens_.end()-2, + [base, this](auto& token) { + token.second += base; + this->length_ += base; + } + ); -void LineAccumulator::discharge(const bool full) { - if ( full ) { - auto range = this->random_.makeRange(0, this->spaces_.size()-1); + auto range = this->random_.makeRange(0, this->tokens_.size()-2); while ( this->length_ < this->max_length_ ) { - this->increase_space_at(range.get()); + this->tokens_[range.get()].second += 1; + this->length_ += 1; } } for ( const auto& token : this->tokens_ ) { - std::cout << token; + std::cout << token.first + << std::string(token.second, ' '); } std::cout << '\n'; this->length_ = 0; this->tokens_.clear(); - this->spaces_.clear(); } diff --git a/src/line_accumulator.h b/src/line_accumulator.h index ea813a9..b3e78de 100644 --- a/src/line_accumulator.h +++ b/src/line_accumulator.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -15,16 +16,12 @@ class LineAccumulator { private: const std::size_t max_length_; - utility::Random random_; - std::size_t length_; - std::vector tokens_; - std::vector spaces_; + utility::Random random_; + std::size_t length_; - void add_token(const std::string& token); - void add_space(); - - void increase_space_at(const std::size_t index); - void pop_trailing_token(); + std::vector< + std::pair + > tokens_; void discharge(const bool full); -- cgit v1.2.3