int StupidFindDistanceBetweenSequences(const Sequence<iterator>& first_sequence, const Sequence<iterator>& second_sequence) { int first_sequence_length = first_sequence.GetLength(); int second_sequence_length = second_sequence.GetLength(); std::vector< std::vector<int> > answer(first_sequence_length + 1, std::vector<int>(second_sequence_length + 1)); for (int i = 0; i <= first_sequence_length; ++i) { for (int j = 0; j <= second_sequence_length; ++j) { if (i == 0 || j == 0) { answer[i][j] = 0; continue; } if (*(first_sequence.GetBegin() + i - 1) == *(second_sequence.GetBegin() + j - 1)) { answer[i][j] = answer[i - 1][ j - 1] + 1; } else { answer[i][j] = 0; } answer[i][j] = std::max(answer[i - 1][j], std::max(answer[i][j], answer[i][j - 1])); } } return (second_sequence_length - answer[first_sequence_length][second_sequence_length]) + (first_sequence_length - answer[first_sequence_length][second_sequence_length]); }
void TestOneIterationOfAlgorythm(const Sequence<iterator>& first_sequence, const Sequence<iterator>& second_sequence) { int first_sequence_length = first_sequence.GetLength(); int second_sequence_length = second_sequence.GetLength(); Massiv diag_checker(second_sequence_length, first_sequence_length); diag_checker[0] = MaxCommonPrefix(first_sequence, second_sequence); int distance_between_sequences = FindDistanceBetweenSequences(first_sequence, second_sequence); int left_border = std::min(distance_between_sequences, second_sequence_length); if (left_border % 2 != distance_between_sequences % 2) left_border--; int right_border = std::min(distance_between_sequences, first_sequence_length); if (right_border % 2 != distance_between_sequences % 2) right_border--; for (int i = 0; i < std::min(second_sequence_length, first_sequence_length); ++i) { OneIterationOfAlgorythm(first_sequence, second_sequence, &diag_checker, i); for (int diag_number = -left_border; diag_number <= right_border; diag_number += 2) { Sequence<iterator> first_checking_sequence(first_sequence.GetBegin(), first_sequence.GetBegin() + diag_checker[diag_number]); Sequence<iterator> second_checking_sequence(second_sequence.GetBegin(), second_sequence.GetBegin() + diag_checker[diag_number] - diag_number); if (StupidFindDistanceBetweenSequences(first_checking_sequence, second_checking_sequence) != i) throw std::logic_error("TestOneIterationOfAlgorythm : FAIL"); } } }
void TestFindOverlapPoint(const Sequence<iterator>& first_sequence, const Sequence<iterator>& second_sequence) { int distance_between_sequences = FindDistanceBetweenSequences(first_sequence, second_sequence); iterator first_begin = first_sequence.GetBegin(); iterator second_begin = second_sequence.GetBegin(); iterator first_end = first_sequence.GetEnd(); iterator second_end = second_sequence.GetEnd(); Point point = FindOverlapPoint(distance_between_sequences, first_sequence, second_sequence); Sequence<iterator> left_first_sequence(first_begin, first_begin + point.x_); Sequence<iterator> left_second_sequence(second_begin, second_begin + point.y_); Sequence<iterator> right_first_sequence(first_begin + point.x_, first_end); Sequence<iterator> right_second_sequence(second_begin + point.y_, second_end); int distance_left = FindDistanceBetweenSequences(left_first_sequence, left_second_sequence); int distance_right = FindDistanceBetweenSequences(right_first_sequence, right_second_sequence); int distance_full = FindDistanceBetweenSequences(first_sequence, second_sequence); if ( !(distance_full == distance_left + distance_right && distance_left - distance_right <= 1 && distance_left - distance_right >= -1) ) throw std::logic_error("TestFindOverlapPoint: FAIL"); }