我目前正在处理Ruby问题,其中我基本上是在创建自己的语言。下面(名词,动词,文章)可以被认为是单词。但是,为了创建一个有效的句子,我必须有动词,名词或至少2篇文章。
名词:" abcd"," c"," def"," h"," ij,&#34 ; CDE"
动词:&#34; bc&#34;,&#34; fg&#34;,&#34; g&#34;,&#34; hij&#34;,&#34; bcd&#34; < / p>
文章:&#34; a&#34;,&#34; ac&#34;,&#34; e&#34;
所以我要做的就是写一个方法,它接受一个字符串并返回所有可能的有效句子(同时保持字符的顺序相同,并在单词之间插入一个空格)
离。输入= "abcdefg"
返回列表
[ "a bc def g", "a bcd e fg", "abcd e fg"]
所以我试着解决问题,这就是我到目前为止所做的
alpha = "abcdefg"
nouns = ["abcd", "c", "def", "h", "ij", "cde"]
verbs = ["bc", "fg", "g", "hij", "bcd"]
articles = ["a", "ac", "e"]
verbArray = [];
nounArray = [];
articleArray = [];
nouns.each do |item|
if alpha.include?(item)
nounArray << item
end
end
verbs.each do |item|
if alpha.include?(item)
verbArray << item
end
end
articles.each do |item|
if alpha.include?(item)
articleArray << item
end
end
puts nounArray.inspect => ["abcd", "c", "def", "cde"]
puts verbArray.inspect => ["bc", "fg", "g", "bcd"]
puts articleArray.inspect => ["a", "e"]
我的思维过程是我首先想要为每个单词(名词,动词,文章)获得所有可能的组合。我不确定这是否是解决这个问题的最有效方法,但是除了这一步之外我还没有成功地形成有序的句子。
我一直在搜索堆栈和其他网站以寻找组合/排序技术的类型,而且我正试图避免使用正则表达式。我会诚实地感谢任何方向/反馈如何继续我解决这个问题的旅程。谢谢你的时间!
答案 0 :(得分:1)
没有正则表达式是可能的,但是在没有递归的情况下你很难写任何东西:
grammar = {
noun: ["abcd", "c", "def", "h", "ij", "cde"],
verb: ["bc", "fg", "g", "hij", "bcd"],
article: ["a", "ac", "e"]}
def find_sentences(text, grammar, head = [], structure = [])
if text.empty?
if structure.include?(:verb) || structure.include?(:noun) || structure.count(:article) > 2
puts "Sentence found : "
puts head.join(' ')
puts structure.join(' ')
puts
end
else
grammar.each do |type, words|
words.each do |word|
if text.start_with?(word)
find_sentences(text.slice(word.size..-1), grammar, head + [word], structure + [type])
end
end
end
end
end
find_sentences("abcdefg", grammar)
输出:
Sentence found :
abcd e fg
noun article verb
Sentence found :
a bc def g
article verb noun verb
Sentence found :
a bcd e fg
article verb article verb
答案 1 :(得分:1)
这是编写递归方法的另一种方法。
def all_sentences(str, grammar)
gram = grammar.each_with_object({}) { |(k,v),h|
v.select { |s| str.include?(s) }.each { |s| h[s] = k } }
recurse(str, gram.keys, gram, '')
end
def recurse(str, parts, gram, partial)
p = partial.delete(' ')
parts.each_with_object([]) do |part, arr|
combine = p + part
next unless str.start_with?(combine)
s = (partial + ' ' + part).lstrip
if combine.size == str.size
arr << s if valid?(s, gram)
else
arr.concat(recurse(str, parts, gram, s))
end
end
end
def valid?(candidate, gram)
arr = candidate.split
arr.any? { |s| [:noun, :verb].include?(gram[s]) } ||
arr.count { |s| gram[s] == :article } > 1
end
示例强>
grammar = {
noun: ["abcd", "c", "def", "h", "ij", "cde"],
verb: ["bc", "fg", "g", "hij", "bcd"],
article: ["a", "ac", "e"]
}
str = "abcdefg"
all_sentences(str, grammar)
#=> ["abcd e fg", "a bc def g", "a bcd e fg"]
注意强>
对于该示例,哈希gram
计算如下。
gram = grammar.each_with_object({}) { |(k,v),h|
v.select { |s| str.include?(s) }.each { |s| h[s] = k } }
#=> {"abcd"=>:noun, "c"=>:noun, "def"=>:noun, "cde"=>:noun,
# "bc"=>:verb, "fg"=>:verb, "g"=>:verb, "bcd"=>:verb,
# "a"=>:article, "e"=>:article}
请注意,除了将单词映射到词性之外,我还删除了一些不能成为“句子”str
一部分的“单词”。
让我感到震惊
words_to_pos = grammar.each_with_object({}) { |(k,v),h| v.each { |s| h[s] = k } }
#=> {"abcd"=>:noun, "c"=>:noun, "def"=>:noun, "h"=>:noun, "ij"=>:noun,
# "cde"=>:noun, "bc"=>:verb, "fg"=>:verb, "g"=>:verb, "hij"=>:verb,
# "bcd"=>:verb, "a"=>:article, "ac"=>:article, "e"=>:article}
将是比原始grammar
(“词性”的“pos”)更方便的数据结构。
答案 2 :(得分:0)
在ruby中使用递归和lambda解决:
@nouns = ["abcd", "c", "def", "h", "ij", "cde"]
@verbs = ["bc", "fg", "g", "hij", "bcd"]
@articles = ["a", "ac", "e"]
@return_arr = []
def solve(idx, hash, ans = [])
# base case
if (idx >= $str.length) and ( hash['vs'] >= 1) and (hash['ns'] >= 1 or hash['as'] >= 2)
@return_arr << ans.join(" ")
return
end
# define lamda to do common operation
execute = lambda do |var, i|
hash[var] += 1
ans << $str[idx..i]
solve(i+1, hash, ans)
ans.pop
hash[var] -= 1
end
#check for nouns, verbs, articles
$str.each_char.with_index do |c,i|
next if i < idx
execute.call('ns', i) if @nouns.include? $str[idx..i]
execute.call('vs', i) if @verbs.include? $str[idx..i]
execute.call('as', i)if @articles.include? $str[idx..i]
end
end
$str = gets.strip
hash = Hash.new(0)
solve(0, hash)
p @return_arr
输入:abcdefg
输出:["a bc def g", "a bcd e fg", "abcd e fg"]