从整数中选择重复数字的字符串

Selecting strings of repeated digits from an integer

提问人:ravish sharma 提问时间:2/26/2023 最后编辑:ruakhravish sharma 更新时间:3/3/2023 访问量:145

问:

我需要编写一个程序,在给定一个整数的情况下,查找重复数字的字符串并将它们作为数组返回。例如,给定 ,程序需要返回 。1234555567899944[5555, 999, 44]

这是我目前所拥有的:

a = 1234555567899944
arr = a.to_s.split("")
result = []
arr.each_with_index do |x,y| 
  if arr[y] == arr[y+1] || arr[y] == arr[y-1]
    result << x
  end
end
p result.join().split()

有没有更好的方法?

我怎样才能得到而不是?[5555, 999, 44]["555599944"]

数组 ruby 字符串

评论


答:

2赞 Rajagopalan 2/26/2023 #1

输入

a = 1234555567899944

p a.to_s.gsub(/(.)(?<=)\1+/).map(&:to_i) 

输出

[5555, 999, 44]

正如Carry所建议的,

a.to_s.gsub(/(.)\1+/).map(&:to_i)

评论

0赞 Rajagopalan 2/26/2023
@spickermann 太棒了,谢谢。我也在答案中包含了你的答案。
0赞 Cary Swoveland 2/26/2023
您可能会提到您正在使用 的形式 它接受单个参数且没有块,并返回一个枚举器,并且由于它处理捕获组的方式而无法使用。gsubscan
0赞 Rajagopalan 2/27/2023
@carySwoveland 感谢您引起我的注意。
0赞 Sachin Singh 2/27/2023 #2

为此,您可以使用 ruby 的 chunk_while 方法:

a = 1234555567899944
a.to_s.split("").chunk_while(&:==).map { |repeated_elems| repeated_elems.join('').to_i if repeated_elems.count > 1 }.compact

评论

1赞 Cary Swoveland 2/27/2023
你可以写.请参阅 Enumerable#filter_map。注意可以就地使用。请参阅 Enumerable#slice_whena.to_s.chars.chunk_while(&:==).filter_map { |a| a.join.to_i if a.count > 1 }slice_when(&:!=)chunk_while(&:==)
1赞 Cary Swoveland 2/27/2023 #3

作为练习,我考虑了如何获得所需的结果,而不会采用可以说是丑陋的方法,即将给定的整数转换为字符串,操纵该字符串以形成相等字符的字符串数组,然后将后者转换回整数。

这是一种可以做到的方法。

a = 1234555567899944
buf = nil
arr = []

loop do
  a, digit = a.divmod(10)
  if buf.nil?
    buf = digit
  elsif digit == buf % 10 
    buf = 10*buf + digit
  else
    arr.unshift(buf) if buf > 10
    buf = digit
  end
  break arr if a.zero?
end
  #=> [5555, 999, 44] 

请参阅 Integer#divmod

评论

0赞 Cary Swoveland 2/27/2023
尽管我避免的方法很丑陋,但在实践中,我会捂着鼻子接受@Rajagopalan的答案(假设我以编码为生)。
0赞 ravish sharma 2/27/2023
是的,@cary Swoveland 你是对的,我们可以选择不同的方法来获得结果,但当涉及到我们选择的最佳和精确的方法时。
1赞 steenslag 2/27/2023 #4

使用 Integer#digits

a = 1234555567899944
p a.digits.chunk(&:itself).filter_map{|_char, chunk| chunk.join.to_i if chunk.size > 1}.reverse
0赞 user16452228 3/2/2023 #5

还可以以至少几种不同的方式使用:scan

a = 1234555567899944

a.to_s.scan(/((.)\2+)/).map{|x| x.first.to_i}
#=>  [5555, 999, 44]

a.to_s.scan(/1{2,}|2{2,}|3{2,}|4{2,}|5{2,}|6{2,}|7{2,}|8{2,}|9{2,}|0{2,}/).map(&:to_i)
#=>  [5555, 999, 44]

请注意,在第一个示例中,该方法不仅捕获了整体重复模式,还捕获了内部模式。第二种方法只是显式匹配重复 2 次或更多次的特定数字,因此没有额外的匹配项需要清除。scan(.)