我有两个字符串,s1
和s2
我想要一个字符列表(来自两个字符串),已排序:
e.g。 "hello"
,"goodbye"
为"lloogbehyd"
e.g。 "hello"
,"goodbye"
为"lloohegdby"
e.g。 "hello"
,"goodbye"
为"lloohebdgy"
目前我有这段代码:
letters = (s1+s2).chars.uniq.sort_by{ |s| [s1.count(s), s2.count(s)].max }.reverse
按第一个条件排序,如何添加其他级别?
答案 0 :(得分:0)
使用String#count效率相对较低,因为遍历每个唯一字母的整个字符串。以更多代码行为代价创建计算哈希会更有效率,可以按照以下方式完成(参见Hash::new)。
s1 = "hello"
s2 = "goodbye"
h1 = s1.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
#=> {"h"=>1, "e"=>1, "l"=>2, "o"=>1}
h2 = s2.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
#=> {"g"=>1, "o"=>2, "d"=>1, "b"=>1, "y"=>1, "e"=>1}
hmx = (h1.keys | h2.keys).each_with_object({}) do |c,h| h[c] =
case h1[c] <=> h2[c]
when 1 then [-h1[c], -1]
when 0 then [-h1[c], 0]
else [-h2[c], 1]
end
end
#=> {"h"=>[-1, -1], "e"=>[-1, 0], "l"=>[-2, -1], "o"=>[-2, 1],
# "g"=>[-1, 1], "d"=>[-1, 1], "b"=>[-1, 1], "y"=>[-1, 1]}
我们现在可以使用排序 Enumerable#sort_by
(s1+s2).each_char.sort_by { |c| [*hmx[c], c] }.join
#=> "lloooheebdgy"
有关如何对数组进行排序的说明,请参阅Array#<=>(第三段)。
我假设如果两个字符中的一个中出现最多出现两个字符,则会为每个字符分配-1
,0
或1
的分数。得分最低的角色(如果他们没有相同的分数)在排序中的另一个角色之前。如果字符c
包含的字符-1
比字符串s1
多,则c
字符的分数为s1
;如果两个字符串包含相同数量的0
,则得分为c
;如果1
包含的s2
比c
更多,则得分为s1
。
答案 1 :(得分:0)
我最终做了什么:
(s1+s2).chars.sort_by{ |s|
[-([s1.count(s), s2.count(s)].max),
s1.count(s) > s2.count(s) ? -1 : 1,
s]
}
#=> "lloohebdgy"
广义的答案是,Array
块sort_by
允许您指定排序级别。