尝试创建一个函数来计算字符串中不止一次出现的字母数(不一定在一起,而不是它们重复的次数)。这就是我所拥有的:
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'))
出于某种原因,如果在字符串的其余部分中使用了第一个字母,它只会推送字符串的第一个字母,但在此之后,似乎该方法会停止循环遍历字符串的其余部分。
我想首先了解当前代码无效的原因,以及是否有办法解决问题,我也欢迎其他更好的解决方案。
答案 0 :(得分:7)
这是一种正统的做法:
'sldhelanlaskjkajksda'.each_char.group_by(&:itself).count{|_, v| v.length > 1}
# => 6
<小时/> 您的代码不起作用的原因是,(i)一旦
i2
循环终止,您递增i1
,并在下一个i2
迭代中尝试另一个i1
循环,但由于未能满足循环条件后未触及i2
,因此它不会再次满足条件,并且i2
循环将永远不会再次运行,并且(ii)您正在初始化{ {1}}为常数。
要解决此问题,请在开头的i2
循环中初始化i2
,并将其初始化为i1
,而不是i2 = i1 + 1
。
答案 1 :(得分:2)
另一种方式:
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
我的回答here中定义了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
答案 2 :(得分:2)
这些答案都没有考虑到OP要求重复字母
但这样做:
'sldhe-lanlas-kjkajksda'.scan(/([a-z])(?=.*\1)/i).uniq.size
#=> 6
答案 3 :(得分:1)
这是您的问题的解决方案
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'))
答案 4 :(得分:0)
创建哈希并将默认值设置为0.使用gsub方法从字符串中删除所有空格。使用split方法将字符串转换为字符串字符数组。迭代数组中的每个字母并将密钥存储为每个字母和每个字母出现的次数作为键的值。最后,使用小于2的值从哈希中删除任何键。返回哈希的长度,因为这对应于哈希中原始字符串中出现多次的字母数。希望这个解释有所帮助,它可以回答你的问题。下面的代码可能更紧凑,但它目前的形式是希望更具说明性和信息量。
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