用 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
在我的语言中有复合或复合字母,它们由多个字符组成,例如"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