Как убрать 3 или более одинаковых персонажа - PullRequest
0 голосов
/ 18 ноября 2018

Во время уроков по Ruby я наткнулся на это упражнение. Я пытаюсь удалить 3 или более одинаковых символов подряд. Тестовые случаи Входные данные: abbbaaccada Выходные данные: ccada Входные данные: bbccdddcb Выходные данные: (пустая строка)

Пока у меня есть решение, которое не дает ожидаемых результатов:

def playground("abbbaaccada")
  count = string.length
  string.chars.each_with_index.map { |v, i| (v * (count - i)).capitalize }.join('')
end

output gives me
==> AaaaaaaaaaaBbbbbbbbbbBbbbbbbbbBbbbbbbbAaaaaaaAaaaaaCccccCcccAaaDdA
instead of
==> ccada

Не могли бы вы посоветовать?

Edit: Забыл добавить, что регулярное выражение не разрешено

Ответы [ 4 ]

0 голосов
/ 19 ноября 2018

(Я хотел прокомментировать, но это пока не позволяет мне делать это.) Предполагая, что вы пытаетесь учиться, я решил дать вам только несколько советов, избегая при этом решения.

Могут быть более короткие способы сделать это с помощью регулярных выражений или / и некоторых методов String. Однако вы сказали, что не можете использовать регулярные выражения.

Мой совет: попытайтесь решить ее, используя разделы, которые вы уже рассмотрели . Возможно, это не самое элегантное решение, но вы можете пересмотреть его по мере продвижения. Как и предполагали другие, рекурсия может быть хорошим вариантом. Но, если вы еще не знакомы с этим, вы можете попробовать нарезать строку и объединить нужные вам части. Это можно комбинировать с бесконечным циклом, чтобы проверить, что новая строка удовлетворяет вашим условиям: но подумайте о , когда вам нужно выйти из цикла .

Также в вашем коде:

v * (count - i)

String # * фактически дает вам count - i копий v, соединенных вместе.

0 голосов
/ 18 ноября 2018
def recursively_remove_runs_of_3_or_more(str)
  arr = str.chars
  loop do
    a = arr.slice_when { |a,b| a.downcase != b.downcase }.to_a
    b = a.reject! { |e| e.size > 2 }
    arr = a.flatten
    break arr.join if b.nil?
  end
end

recursively_remove_runs_of_3_or_more "abbbaaccada"
  #=> "ccada"

Используется Enumerable # slice_when (новое в MRI v2.2).Обратите внимание, что Array # reject! возвращает nil, если не было внесено никаких изменений.

Вы также можете использовать Enumerable # chunk_ while (новое в MRI v2.3).Просто замените:

    a = arr.slice_when { |a,b| a.downcase != b.downcase }.to_a

на:

    a = arr.chunk_while { |a,b| a.downcase == b.downcase }.to_a

chunk_while и slice_when - это Инь и Ян.

Если можно использовать регулярное выражение и регистргде не проблема, вы можете написать:

str = "abbbaaccada"
s = str.dup
loop { break(s) if s.gsub!(/(.)\1{2,}/, '').nil? }
  #=> "ccada"
0 голосов
/ 18 ноября 2018

Вот потенциальное решение. Следующий метод ищет любую подпоследовательность массива с повторениями и возвращает диапазон повторных значений, если их три или более.

def find_3_or_more(ary)
  ary.each_index do |i|
    j = i + 1
    while j < ary.length && ary[i] == ary[j]
      j += 1
    end
    return (i...j) if j - i > 2
  end
  nil
end

Эта часть разбивает целевую строку на массив символов и многократно вырезает символы в диапазонах, определенных как повторы, до тех пор, пока их нет, как указано в диапазоне nil.

def delete_3_or_more(str)
  ary = str.chars
  while r = find_3_or_more(ary)
    ary.slice!(r)
  end
  return ary.join
end

Кажется, он подходит для ваших тестовых случаев.

0 голосов
/ 18 ноября 2018

Здесь есть две проблемы:

  • Совпадение и удаление всех символов подряд или более
  • Повторите тестирование снова, если предыдущий шаг создал новый прогон из трех

Вот один из способов сделать это:

THREE_OR_MORE = /(.)\1{2,}/
def three_is_too_many(str)
  if str.match? THREE_OR_MORE
    str = three_is_too_many(str.gsub(THREE_OR_MORE, ''))
  end
  str
end

Регулярное выражение находит любой символ ('.'), За которым следует сам ('\ 1'), два или более раз ('{2,}').

Затем подпрограмма либо a) удаляет три или более и проверяет снова, либо b) возвращает строку.

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