返回字符串中重复的字母数的函数

试图创建一个函数来计算字符串中不止一次出现的字母数(不一定在一起,而不是它们重复的次数)。 这就是我所拥有的:

def num_repeats(string) repeat = [] i1 = 0 i2 = 1 while i1 < string.length while i2 < string.length if (string[i1] == string[i2]) && (!repeat.include? string[i1]) repeat << string[i1] end i2 +=1 end i1+=1 end return repeat.length end puts(num_repeats('sldhelanlaskjkajksda')) 

出于某种原因,如果在字符串的其余部分中使用了第一个字母,它只会推送字符串的第一个字母,但在此之后,似乎该方法会停止循环遍历字符串的其余部分。

我想首先了解当前代码无法正常工作的原因,以及是否有办法解决这个问题,我也欢迎其他更好的解决方案。

这是一种正统的方式:

 'sldhelanlaskjkajksda'.each_char.group_by(&:itself).count{|_, v| v.length > 1} # => 6 

您的代码不起作用的原因是,(i)一旦i2循环终止,您递增i1 ,并在下一次i1迭代中尝试另一个i2循环,但因为在未能满足循环条件后未触及i2 ,它不会再次满足条件,并且i2循环将永远不会再次运行,并且(ii)您正在将i2初始化为常量。

要解决此问题,请在开始时在i1循环内初始化i2 ,并将其初始化为i2 = i1 + 1 ,而不是1

其他方式:

 s = 'sldhelanlaskjkajksda' a = s.chars #=> ["s", "l", "d", "h", "e", "l", "a", "n", "l", "a", # "s", "k", "j", "k", "a", "j", "k", "s", "d", "a"] a.difference(a.uniq).uniq.size #=> 6 

其中Array#difference在我的答案中定义。

我们有:

 b = a.uniq #=> ["s", "l", "d", "h", "e", "a", "n", "k", "j"] c = a.difference(b) #=> ["l", "l", "a", "s", "k", "a", "j", "k", "s", "d", "a"] d = c.uniq #=> ["l", "a", "s", "k", "j", "d"] d.size #=> 6 

这些答案都没有考虑到OP要求重复的字母

但这样做:

 'sldhe-lanlas-kjkajksda'.scan(/([az])(?=.*\1)/i).uniq.size #=> 6 

这是您的问题的解决方案

  def num_repeats(string) repeat = [] i1 = 0 i2 = 1 while i1 < string.length while i2 < string.length if (string[i1] == string[i2]) && !(repeat.include? string[i1]) repeat << string[i1] end i2 +=1 end i1+=1 i2 = i1 + 1 end return repeat.length end puts(num_repeats('sldhelanlaskjkajksda')) 

这里有点简单(希望)和小Ruby-ish,解决方案:

 def num_repeats(string) # chars in string chars = string.split('') # initialize map - for each char, count is initialized to 0 hash = chars.uniq.inject({}) { |h, c| h[c] = 0; h} # for each char in string, lets count its occurrences chars.each do |c| hash[c] += 1 end # now lets pick those entries from the map where the count is > 1 hash_with_repeated_chars = hash.select {|k, v| v > 1 } # now lets pick the chars that are repeated by picking keys of hash repeated_chars = hash_with_repeated_chars.select { |k, v| k} # return the count of repeated chars return repeated_chars.count end p num_repeats('abc') # Prints 0 p num_repeats('abbc') # Prints 1 p num_repeats('abbcc') # Prints 2 p num_repeats('aabbcc') # Prints 3 

我还有一个与所有其他答案不同的Ruby版本(因此,由于它在内部进行了多次迭代,因此效率低下)

 s = 'sldhelanlaskjkajksda' p s.chars.combination(2).to_a.uniq.map(&:sort).map(&:uniq).select{|a| a.size.eql?(1)}.count 

创建哈希并将默认值设置为0.使用gsub方法从字符串中删除所有空格。 使用split方法将字符串转换为字符串字符数组。 迭代数组中的每个字母并将密钥存储为每个字母和每个字母出现的次数作为键的值。 最后使用小于2的值从哈希中删除任何键。返回哈希的长度,因为这对应于哈希中原始字符串中出现多次的字母数。 希望这个解释有所帮助,它可以回答你的问题。 下面的代码可能更紧凑,但它目前的forms是希望更具说明性和信息量。

  def counter(string) counts = Hash.new(0) result = string.gsub(" ","") result = result.split('') result.each do |letter| counts[letter] += 1 end counts.delete_if { |key,value| value < 2} return counts.length end