用 Ruby 将单词分解成字母

Decompose words into letters with Ruby

在我的语言中有复合或复合字母,它们由多个字符组成,例如"ty"、"ny"甚至"tty"和"nny"。我想写一个 Ruby 方法(拼写),根据这个字母表将单词标记为字母:

abc=[*%w{tty ccs lly ggy ssz nny dzs zzs sz zs cs gy ny dz ty ly q w r t z p l k j h g f d s x c v b n m y}.map{|z| [z,"c"]},*"eéuioöüóőúűáía".split(//).map{|z| [z,"v"]}].to_h

生成的哈希键显示字母表中现有的字母/复合字母,还显示哪个字母是辅音字母 ("c") 哪个字母是元音字母 ("v"),因为以后我想用这个哈希将单词分解成音节。不小心在单词公共边界处形成复合字母的复合词当然不能通过该方法解决。

示例:

spell("csobolyó") => [ "cs", "o", "b", "o", "ly", "ó" ]
spell("nyirettyű") => [ "ny", "i", "r", "e", "tty", "ű" ]
spell("dzsesszmuzsikus") => [ "dzs", "e", "ssz", "m", "u", "zs", "i", "k", "u", "s" ]

您可以开始查看 String#scan,它似乎为您的示例提供了不错的结果:

"csobolyó".scan(Regexp.union(abc.keys))
# => ["cs", "o", "b", "o", "ly", "ó"]
"nyirettyű".scan(Regexp.union(abc.keys))
# => ["ny", "i", "r", "e", "tty", "ű"]
"dzsesszmuzsikus".scan(Regexp.union(abc.keys))
# => ["dzs", "e", "ssz", "m", "u", "zs", "i", "k", "u", "s"]

最后一个案例与您预期的输出不匹配,但它匹配

I sorted the letters in the alphabet: if a letter appears earlier, then it should be recognized instead of its simple letters. When a word contains "dzs" it should be considered to "dzs" and not to "d" and "zs"

我没有使用您排序的首选项,而是我使用了较高字符的词比较低字符的词具有更高的偏好。

def spell word
  abc=[*%w{tty ccs lly ggy ssz nny dzs zzs sz zs cs gy ny dz ty ly q w r t z p l k j h g f d s x c v b n m y}.map{|z| [z,"c"]},*"eéuioöüóőúűáía".split(//).map{|z| [z,"v"]}].to_h
  current_position = 0
  maximum_current_position = 2
  maximum_possible_position = word.length
  split_word = []
  while current_position < maximum_possible_position do 
    current_word = set_current_word word, current_position, maximum_current_position
    if abc[current_word] != nil
      current_position, maximum_current_position = update_current_position_and_max_current_position current_position, maximum_current_position
      split_word.push(current_word)
    else
      maximum_current_position = update_max_current_position maximum_current_position
      current_word = set_current_word word, current_position, maximum_current_position
      if abc[current_word] != nil
        current_position, maximum_current_position = update_current_position_and_max_current_position current_position, maximum_current_position
        split_word.push(current_word)
      else
        maximum_current_position = update_max_current_position maximum_current_position
        current_word = set_current_word word, current_position, maximum_current_position
        if abc[current_word] != nil
          current_position, maximum_current_position = update_current_position_and_max_current_position current_position, maximum_current_position          
          split_word.push(current_word)
        else
          puts 'This word cannot be formed in the current language'
          break
        end
      end
    end
  end
  split_word
end

def update_max_current_position max_current_position
    max_current_position = max_current_position - 1
end

def update_current_position_and_max_current_position current_position,max_current_position
    current_position = max_current_position + 1
    max_current_position = current_position + 2
    return current_position, max_current_position
end

def set_current_word word, current_position, max_current_position
  word[current_position..max_current_position]
end

puts "csobolyó => #{spell("csobolyó")}"
puts "nyirettyű => #{spell("nyirettyű")}"
puts "dzsesszmuzsikus => #{spell("dzsesszmuzsikus")}"

输出

csobolyó => ["cs", "o", "b", "o", "ly", "ó"]
nyirettyű => ["ny", "i", "r", "e", "tty", "ű"]
dzsesszmuzsikus => ["dzs", "e", "ssz", "m", "u", "zs", "i", "k", "u", "s"]

与此同时,我设法编写了一个有效的方法,但比 String#scan:

慢 5 倍
abc=[*%w{tty ccs lly ggy ssz nny dzs zzs sz zs cs gy ny dz ty ly q w r t z p l k j h g f d s x c v b n m y}.map{|z| [z,"c"]},*"eéuioöüóőúűáía".split(//).map{|z| [z,"v"]}].to_h

def spell(w,abc)


    s=w.split(//)
    p=""
    t=[]

    for i in 0..s.size-1 do
      p << s[i]
      if i>=s.size-2 then

       if abc[p]!=nil then
          t.push p
          p=""

       elsif abc[p[0..-2]]!=nil then
          t.push p[0..-2]
          p=p[-1]

       elsif abc[p[0]]!=nil then
          t.push p[0]
          p=p[1..-1]

       end 

      elsif p.size==3 then
       if abc[p]!=nil then
          t.push p
          p=""

       elsif abc[p[0..-2]]!=nil then
          t.push p[0..-2]
          p=p[-1]

       elsif abc[p[0]]!=nil then
          t.push p[0]
          p=p[1..-1]
       end
      end
    end

    if p.size>0 then
        if abc[p]!=nil then
          t.push p
          p=""

       elsif abc[p[0..-2]]!=nil then
          t.push p[0..-2]
          p=p[-1]
      end
    end

    if p.size>0 then
      t.push p
    end
    return t
end