怎样优雅的研究 RGSS3 番外(一) ruby 实现的后缀自己主动机

*我真的不会 ruby 呀*



#encoding:utf-8
#==============================================================================
# ■ Suffix_Automaton
#------------------------------------------------------------------------------
#  后缀自己主动机。
#==============================================================================

class Suffix_Automaton
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader   :total                   # 当前 SAM 中不同的子串个数
  attr_reader   :root                    # SAM 的根节点
  #==============================================================================
  # ■ State
  #------------------------------------------------------------------------------
  #  后缀自己主动机的状态结点。
  #==============================================================================
  class State
    #--------------------------------------------------------------------------
    # ● 定义实例变量
    #--------------------------------------------------------------------------
    attr_accessor   :par                     # parent 树中的父结点
    attr_accessor   :go                      # go
    attr_accessor   :val                     # val
    #--------------------------------------------------------------------------
    # ● 初始化状态结点
    #--------------------------------------------------------------------------    
    def init(val = 0)
      @par = nil
      @go = []
      @val = val
      for i in 0..26 do
        @go[i] = nil
      end
    end
    #--------------------------------------------------------------------------
    # ● 计算结点表示的不同子串数
    #--------------------------------------------------------------------------
    def calc
      return 0 if @par == nil
      return @val - @par.val
    end
  end
  #--------------------------------------------------------------------------
  # ● 初始化后缀自己主动机
  #--------------------------------------------------------------------------    
  def initSAM
    @total = 0
    @cur = 0
    @nodePool = []
    @root = newState
    @last = @root
  end
  #--------------------------------------------------------------------------
  # ● 创建新的状态结点
  #--------------------------------------------------------------------------    
  def newState(val = 0)
    @nodePool[@cur] = State.new
    @nodePool[@cur].init(val)
    @cur += 1
    return @nodePool[@cur-1]
  end
  #--------------------------------------------------------------------------
  # ● 加入字符
  #--------------------------------------------------------------------------    
  def extend(w)
    p = @last
    np = newState(p.val + 1)
    while p != nil and p.go[w] == nil do
      p.go[w] = np
      p = p.par
    end
    if p == nil
      np.par = @root
      @total += np.calc # 统计
    else
      q = p.go[w]
      if p.val + 1 == q.val
        np.par = q
        @total += np.calc # 统计
      else
        nq = newState(p.val + 1)
        for i in 0..26 do
          nq.go[i] = q.go[i]
        end
        @total -= q.calc # 统计
        nq.par = q.par
        q.par = nq
        np.par = nq
        @total += q.calc + nq.calc + np.calc
        while p != nil and p.go[w] == q do
          p.go[w] = nq
          p = p.par
        end
      end
    end
    @last = np
  end
end  





posted @ 2017-04-26 08:55  yangykaifa  阅读(164)  评论(0编辑  收藏  举报