Сжатие заданной строковой проблемы в Ruby - PullRequest
0 голосов
/ 02 октября 2019

Я уже некоторое время пытаюсь решить эту проблему, я должен взять заданную строку, например "aaabbc", и сжать ее в новую строку, в которой указаны кратные буквы в строке. Таким образом, он вывел бы «3a2bc»

До сих пор мне удалось распечатать его, за исключением того, что он считает все экземпляры буквы, и я не уверен, как избавиться от текущих повторов:

def compress_str(str)

    new_str = []
    word = str.split("")

    word.each do |char|
        count = 0
        word.each do |ele|
            if ele == char
                count += 1
            end
        end
        if count > 1
          new_str << count
          new_str << char
        else
          new_str << char
        end
    end

    return new_str.join("")

Пример вывода:

Sample

Есть предложения о том, как мне от них избавиться?

Ответы [ 3 ]

1 голос
/ 02 октября 2019

Вы можете использовать String # chars (1), поэтому Enumerable # chunk_ while (2), затем Enumerable # flat_map (3) в желаемый формати наконец Array # join :

str = "aaabbcaa"

str.chars.chunk_while { |x, y| x == y }.flat_map { |e| [(e.size unless e.size == 1), e.first] }.join
#=> "3a2bc2a"

Шаг за шагом

# (1)
str.chars#.to_a
#=> ["a", "a", "a", "b", "b", "c", "a", "a"]

, поэтому

# (2)
str.chars.chunk_while { |x, y| x == y }#.to_a
#=> [["a", "a", "a"], ["b", "b"], ["c"], ["a", "a"]]

затем

# (3)
str.chars.chunk_while { |x, y| x == y }.flat_map { |e| [(e.size unless e.size == 1),e.first] }
#=> [3, "a", 2, "b", nil, "c", 2, "a"]
1 голос
/ 02 октября 2019

String#scan также может пригодиться здесь.

uncompressed = %w(aaabbcddaaaaa aaabb 111ddttttabaaacc)
uncompressed.map { |w| w.scan(/(.)(\1*)/).map(&:join) }
#⇒ [["aaa", "bb", "c", "dd", "aaaaa"],
#   ["aaa", "bb"],
#   ["111", "dd", "tttt", "a", "b", "aaa", "cc"]]

И для получения желаемого результата.

uncompressed.map do |w|
  w.scan(/(.)(\1*)/).map(&:join).map do |l|
    "#{l.length}#{l[0]}"
  end.join
end
#⇒ ["3a2b1c2d5a", "3a2b", "312d4t1a1b3a2c"]
1 голос
/ 02 октября 2019

Использование Enumerable # chunk может подойти для ваших нужд.

uncompressed = %w(aaabbcddaaaaa aaabb 111ddttttabaaacc)

uncompressed.each do |str|
  puts str.chars.chunk{|e| e}.map {|e| "#{e[1].length}#{e[0]}"}.join
end

>>> 3a2b1c2d5a
>>> 3a2b
>>> 312d4t1a1b3a2c

Конечно, вы можете добавить еще одну проверку внутри блока карты, поэтому пропустите 1 перед одним элементом и напечатайте как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...