19 #ifndef OTest2__LIB_HIRSCHBERG_H_
20 #define OTest2__LIB_HIRSCHBERG_H_
41 template<
typename Type_>
49 int right_index_)
const {
50 bool same_(left_[left_index_] == right_[right_index_]);
51 return std::make_tuple(same_, same_ ? 1 : -1);
57 int right_index_)
const {
64 int left_index_)
const {
71 return score1_ > score2_;
75 template<
typename Type_,
typename ScoreFce_ = DiffScoreLCS<Type_> >
83 static ScoreRecord selectAction(
84 const ScoreFce_& score_fce_,
90 const ScoreRecord& sub_prev_,
91 const ScoreRecord& del_prev_,
92 const ScoreRecord& ins_prev_) {
95 auto sub_result_(score_fce_.scoreSub(
96 step_, left_, left_index_, right_, right_index_));
97 int sub_score_(sub_prev_.score + std::get<1>(sub_result_));
99 del_prev_.score + score_fce_.scoreDel(step_, right_, right_index_));
101 ins_prev_.score + score_fce_.scoreIns(step_, left_, left_index_));
104 if(score_fce_.betterScore(del_score_, ins_score_)) {
105 if(score_fce_.betterScore(del_score_, sub_score_)) {
109 if(std::get<0>(sub_result_))
116 if(score_fce_.betterScore(ins_score_, sub_score_)) {
120 if(std::get<0>(sub_result_))
128 static void diffScore(
129 const ScoreFce_& score_fce_,
133 const Type_ right_[],
137 std::vector<ScoreRecord>& score_) {
138 assert(step_ == 1 || step_ == -1);
141 const int left_len_(score_.size());
143 for(
int i_(1); i_ < left_len_; ++i_) {
146 score_[i_ - 1].score + score_fce_.scoreIns(
149 left_begin_ + (i_ - 1) * step_)};
154 for(; right_begin_ != right_end_; right_begin_ += step_) {
157 score_[0].score + score_fce_.scoreDel(step_, right_,right_begin_)};
158 for(
int i_(1); i_ < left_len_; ++i_) {
159 next_line_[i_] = selectAction(
163 left_begin_ + (i_ - 1) * step_,
170 score_.swap(next_line_);
174 static void diffImpl(
175 const ScoreFce_& score_fce_,
179 const Type_ right_[],
183 assert(left_begin_ >= 0 && left_end_ >= 0);
184 assert(right_begin_ >= 0 && right_end_ >= 0);
185 assert(left_begin_ <= left_end_ && right_begin_ <= right_end_);
188 if(left_begin_ == left_end_) {
189 for(
int i_(right_begin_); i_ < right_end_; ++i_)
193 else if(right_begin_ == right_end_) {
194 for(
int i_(left_begin_); i_ < left_end_; ++i_)
198 else if(left_begin_ + 1 == left_end_) {
200 ScoreRecord last_del_{
202 score_fce_.scoreIns(1, left_, left_begin_)};
205 for(
int i_(right_begin_); i_ < right_end_; ++i_) {
206 ScoreRecord last_ins_{
208 last_sub_.score + score_fce_.scoreDel(1, right_, i_)};
209 last_del_ = selectAction(
222 change_action_ = last_del_.action;
224 last_sub_ = last_ins_;
226 for(
int i_(right_begin_); i_ < right_end_; ++i_) {
232 diff_log_.
addMatch(left_begin_, i_);
236 else if(right_begin_ + 1 == right_end_) {
238 ScoreRecord last_ins_{
240 score_fce_.scoreDel(1, right_, right_begin_)};
243 for(
int i_(left_begin_); i_ < left_end_; ++i_) {
244 ScoreRecord last_del_{
246 last_sub_.score + score_fce_.scoreIns(1, left_, i_)};
247 last_ins_ = selectAction(
260 change_action_ = last_ins_.action;
262 last_sub_ = last_del_;
264 for(
int i_(left_begin_); i_ < left_end_; ++i_) {
270 diff_log_.
addMatch(i_, right_begin_);
275 const int rmid_((right_begin_ + right_end_) / 2);
276 const int left_len_(left_end_ - left_begin_);
281 std::vector<ScoreRecord> score_pre_(left_len_ + 1);
294 std::vector<ScoreRecord> score_suf_(left_len_ + 1);
307 int score_max_(score_pre_[0].score + score_suf_[left_len_].score);
308 for(
int i_(1); i_ <= left_len_; ++i_) {
309 const int score_(score_pre_[i_].score + score_suf_[left_len_ - i_].score);
310 if(score_ > score_max_) {
359 const ScoreFce_& score_fce_,
361 std::size_t left_len_,
362 const Type_ right_[],
363 std::size_t right_len_,
365 if(left_len_ <= right_len_) {
367 score_fce_, left_, 0, left_len_, right_, 0, right_len_, diff_log_);
375 score_fce_, right_, 0, right_len_, left_, 0, left_len_, reverse_);
390 template<
typename Type_,
typename ScoreFce_ = DiffScoreLCS<Type_> >
393 std::size_t left_len_,
394 const Type_ right_[],
395 std::size_t right_len_,
397 ScoreFce_ score_fce_ = ScoreFce_()) {
400 score_fce_, left_, left_len_, right_, right_len_, log_builder_);
411 template<
typename Type_,
typename ScoreFce_ = DiffScoreLCS<Type_> >
413 const std::vector<Type_>& left_,
414 const std::vector<Type_>& right_,
416 ScoreFce_ score_fce_ = ScoreFce_()) {