我有这个基本问题,如果输入字符串是排列,我希望我的函数返回true,否则返回false。我有一个非常丑陋的解决方案,我希望这样做:
def permutation?(a, b)
p chars_a = a.split('').group_by { |char| char }
p chars_b = b.split('').group_by { |char| char }
chars_a. each do |k, v|
break false unless (chars_b.key?(k) && chars_b[k].count == v.count)
end
end
问题是,当我运行测试时,该函数在返回时不会返回true。我猜这是一个基本的语法问题。您能帮忙吗?
难看的解决方案:
def permutation?(a, b)
p chars_a = a.split('').group_by { |char| char }
p chars_b = b.split('').group_by { |char| char }
sorry = []
chars_a. each do |k, v|
if b = chars_b.key?(k) && chars_b[k].count == v.count
b = true
else
b = false
end
sorry << b
end
if sorry.include?(false)
false
else
true
end
end
each
方法返回其接收者,即您调用它的对象,因此permutation?
方法在返回false
时返回break
,否则返回chars_a
。
您可以通过多种方式解决此问题。您可以在块外创建变量并将其设置为true
或false
,然后在方法末尾返回变量:
def permutation?(a, b)
chars_a = a.chars.group_by {|char| char }
chars_b = b.chars.group_by {|char| char }
result = true
chars_a.each do |k, v|
unless chars_b.key?(k) && chars_b[k].size == v.size
result = false
break
end
end
result
end
您也可以在块内使用return false
代替break false
,否则返回true
:
def permutation?(a, b)
chars_a = a.chars.group_by {|char| char }
chars_b = b.chars.group_by {|char| char }
chars_a.each do |k, v|
return false unless chars_b.key?(k) && chars_b[k].size == v.size
end
true
end
但是,这两个都不是Rubyish。更为惯用的解决方案是用返回each
或true
的方法替换false
。在此all?
非常适合。如果该块为每个项目求出真实值,则返回all?
,否则返回true
:
false
但是,您的逻辑有误。您的方法检查def permutation?(a, b)
chars_a = a.chars.group_by {|char| char }
chars_b = b.chars.group_by {|char| char }
chars_a.all? do |k, v|
chars_b.key?(k) && chars_b[k].size == v.size
end
end
是否包含b
的所有字符,但不包含其他所有字符。
a
这是因为您检查permutation?("antler", "rentals")
# => true
permutation?("rentals", "antler")
# => false
是否包含b
的所有字符,但不包含其他所有字符。一个简单的解决方法是,如果输入的大小不同,则尽早进行纾困:
a
虽然更简洁但速度较慢的解决方案是只检查def permutation?(a, b)
return false unless a.size == b.size
chars_a = a.chars.group_by {|char| char }
chars_b = b.chars.group_by {|char| char }
chars_a.all? do |k, v|
chars_b.key?(k) && chars_b[k].size == v.size
end
end
和chars_a
是否具有相同的键和值,而Ruby使它很容易:
chars_b
在我看来,给定两个字符串,您希望确定第二个字符是否是第一个字符的排列,反之亦然。如果是这样,可以很容易地做到这一点。
def permutation?(a, b)
a.chars.group_by {|char| char } === b.chars.group_by {|char| char }
end
def permutation?(str1, str2)
str1.chars.sort == str2.chars.sort
end
这是另一种可以完成的方式:
permutation?('abc', 'cab') #=> true
permutation?('aba', 'baa') #=> true
permutation?('abc', 'caba') #=> false
permutation?('', '') #=> true
注意:
def permutation?(str1, str2)
hashify(str1) == hashify(str2)
end
def hashify(str)
str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
end
请参见h1 = hashify('aba') #=> {"a"=>2, "b"=>1}
h2 = hashify('baa') #=> {"b"=>1, "a"=>2}
h1 == h2 #=> true
,特别是(秒)形式,该形式采用等于默认值的参数(此处为零)。这意味着如果已定义的Hash::new散列没有键h = Hash.new(0)
,则k
将返回h[k]
。由于以下原因,有时称为counting hash。
Ruby将表达式0
解析为:
h[k] += 1
如果h[k] = h[k] + 1
没有键h
,则右侧的k
将返回h[k]
,因此0
将被设置为等于h[k]
。此后,对于该键1
,右侧的k
将具有正值。