Aquí está mi código en ruby para una compresión de palabras. Para cualquier palabra dada (por ejemplo, abbbcca), la palabra / salida comprimida debe estar en el formato "letra + repetición" (por ejemplo, salida: a1b3c2a1).

Aquí estoy tan cerca de la finalización, pero mi resultado no está en el formato esperado. Está contando todas las letras en string.chars.each, lo que da como resultado la salida como a2b3c2a2.

¿Alguna ayuda?

def string_compressor(string)
  new_string = []
  puts string.squeeze

  string.squeeze.chars.each { |s|
    count = 0

    string.chars.each { |w|
      if [s] == [w]
        count += 1
      end
    }

    new_string << "#{s}#{count}"
    puts "#{new_string}"
  }

  if new_string.length > string.length
    return string
  elsif new_string.length < string.length
    return new_string
  else "Equal"
  end
end

string_compressor("abbbcca")
3
Pa-won 25 dic. 2016 a las 16:43

3 respuestas

La mejor respuesta
'abbbcca'.chars.chunk{|c| c}.map{|c, a| [c, a.size]}.flatten.join

Adaptado de una pregunta similar.

Similar:

'abbbcca'.chars.chunk{|c| c}.map{|c, a| "#{c}#{a.size}"}.join

Consulte documentación del fragmento

2
Community 23 may. 2017 a las 12:33

Como dijiste, tu código cuenta cada letra en la cadena, no solo la agrupada una al lado de la otra.

Aquí hay una versión modificada:

def display_count(count)
  if count == 1
    ""
  else
    count.to_s
  end
end

def string_compressor(string)
  new_string = ''
  last_char = nil
  count = 0

  string.chars.each do |char|
    if char == last_char
      count += 1
    else
      new_string << "#{last_char}#{display_count(count)}" if last_char
      last_char = char
      count = 1
    end
  end

  new_string << "#{last_char}#{display_count(count)}" if last_char

  new_string
end

p string_compressor('abbbcca') #=> "ab3c2a"
p string_compressor('aaaabbb') #=> "a4b3"
p string_compressor('aabb')    #=> "a2b2"
p string_compressor('abc')     #=> "abc"

Tenga en cuenta que con display_count eliminar 1 s de la cadena, new_string nunca puede ser más largo que string. Probablemente tampoco sea una buena idea devolver Equal como una cadena supuestamente comprimida.

Para descomprimir la cadena:

def string_decompressor(string)
  string.gsub(/([a-z])(\d+)/i){$1*$2.to_i}
end

p string_decompressor("a5b11")  #=> "aaaaabbbbbbbbbbb"
p string_decompressor("ab3c2a") #=> "abbbcca"
0
Eric Duminil 25 dic. 2016 a las 18:01

Puedes usar una expresión regular para eso.

'abbbcca'.gsub(/(.)\1*/) { |m| "%s%d" % [m[0], m.size] }
  #=> "a1b3c2a1"

La expresión regular dice: "coincide con cualquier carácter, capturándolo en el grupo 1. Luego, coincide con el contenido del grupo de captura 1 cero o más veces".

1
Cary Swoveland 26 dic. 2016 a las 02:12