class TextAlignment::LCSAlignment

Attributes

common_elements[R]
mapped_elements[R]
position_map_begin[R]
position_map_end[R]

Public Class Methods

new(str1, str2, lcs = nil, sdiff = nil) click to toggle source

It initializes the LCS table for the given two strings, str1 and str2. Exception is raised when nil given passed to either str1, str2 or dictionary

# File lib/text_alignment/lcs_alignment.rb, line 10
def initialize(str1, str2, lcs = nil, sdiff = nil)
        raise ArgumentError, "nil string" if str1 == nil || str2 == nil
        sdiff = TextAlignment::LCSMin.new(str1, str2).sdiff if sdiff.nil?
        _compute_position_map(str1, str2, sdiff)
end

Private Instance Methods

_compute_position_map(str1, str2, sdiff) click to toggle source
# File lib/text_alignment/lcs_alignment.rb, line 18
def _compute_position_map(str1, str2, sdiff)
        posmap_begin, posmap_end = {}, {}
        @common_elements, @mapped_elements = [], []

        addition, deletion = [], []

        sdiff.each do |h|
                case h.action
                when '='
                        p1, p2 = h.old_position, h.new_position

                        @common_elements << [str1[p1], str2[p2]]
                        posmap_begin[p1], posmap_end[p1] = p2, p2

                        if !addition.empty? && deletion.empty?
                                # correct the position for end
                                posmap_end[p1] = p2 - addition.length unless p1 == 0
                        elsif addition.empty? && !deletion.empty?
                                deletion.each{|p| posmap_begin[p], posmap_end[p] = p2, p2}
                        elsif !addition.empty? && !deletion.empty?
                                @mapped_elements << [str1[deletion[0], deletion.length], str2[addition[0], addition.length]]

                                posmap_begin[deletion[0]], posmap_end[deletion[0]] = addition[0], addition[0]
                                deletion[1..-1].each{|p| posmap_begin[p], posmap_end[p] = nil, nil}
                        end

                        addition.clear; deletion.clear

                when '!'
                        deletion << h.old_position
                        addition << h.new_position
                when '-'
                        deletion << h.old_position
                when '+'
                        addition << h.new_position
                end
        end

        p1, p2 = str1.length, str2.length
        posmap_begin[p1], posmap_end[p1] = p2, p2

        if !addition.empty? && deletion.empty?
                # correct the position for end
                posmap_end[p1] = p2 - addition.length unless p1 == 0
        elsif addition.empty? && !deletion.empty?
                deletion.each{|p| posmap_begin[p], posmap_end[p] = p2, p2}
        elsif !addition.empty? && !deletion.empty?
                @mapped_elements << [str1[deletion[0], deletion.length], str2[addition[0], addition.length]]

                posmap_begin[deletion[0]], posmap_end[deletion[0]] = addition[0], addition[0]
                deletion[1..-1].each{|p| posmap_begin[p], posmap_end[p] = nil, nil}
        end

        @position_map_begin = posmap_begin.sort.to_h
        @position_map_end = posmap_end.sort.to_h
end