Создавая приложение за приложением в течение последних нескольких месяцев, я лично забыл многие приемы и приемы, которым научился, когда начинал программировать. Например, методы, которые раньше так укоренились в моей голове, я больше не использовал в повседневной жизни. Но с таким количеством онлайн-ресурсов, документации и моих собственных заметок я могу освежить свои знания.
Но просто читать документацию и заметки недостаточно, но, к счастью, есть много веб-сайтов, на которых можно зарегистрироваться и попрактиковаться с множеством задач по кодированию и / или руководств. Ниже приведен список лишь некоторых из этих типов ресурсов:
- https://www.hackerrank.com
- https://leetcode.com/
- https://www.codewars.com
- https://www.codecademy.com
Ниже я потренируюсь с некоторыми проблемами и покажу некоторые решения, которые я придумал, и объясню свой мыслительный процесс.
Практика №1
Функция #accum принимает строку и выводит следующее:
accum("abcd") # "A-Bb-Ccc-Dddd" accum("RqaEzty") # "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy" accum("cwAt") # "C-Ww-Aaa-Tttt"
Решение №1 с Ruby
def accum(s) new_string = "" s.each_char.with_index do |char, idx| segment = (char * (idx + 1)).capitalize if idx == s.length - 1 new_string << "#{segment}" else new_string << "#{segment}-" end end new_string end
Пошаговая инструкция:
– объявите new_string, чтобы сохранить ответ и вывести его позже. Он будет иметь тип String
- #each_char разбивает строку на отдельные символы. #with_index — это метод цепочки, который предоставляет нам индекс каждого элемента. Используя оба метода, я могу передать char (каждый символ) и idx (индекс символа).
- я объявляю переменную segment и установите его равным строке, созданной путем умножения символа (idx + 1) раз. Метод #capitalize сделает только первую букву прописной, а все остальные — строчными.
— Условие используется, чтобы решить, добавлять ли тире ("-") к конкретному segment или нет, И чтобы поместить его в переменную new_string. Если индекс является последним элементом введенной строки, это означает, что мне не нужно добавлять тире. В противном случае мне придется добавить тире к сегменту.
— Вернуть новую_строку
Решение № 2 с Ruby
def accum(s) answer = [] s.split("").each_with_index do |letter, index| segment = letter.upcase index.times { segment << letter.downcase } answer << segment end answer.join("-") end
Пошаговая инструкция:
– объявите ответ, чтобы сохранить результаты и вывести их позже. Он будет сохранен в виде массива.
– Использование #split разделит строку на массив отдельных символов. Поскольку s теперь представляет собой массив, я могу использовать метод #each_with_index для перебора каждого символа и индекса, я могу передать letter и index, соответственно.
- На каждой итерации я устанавливаю переменную segment, которая будет инициализироваться буквой, переданной в #верхнем регистре. Segment будет строкой.
- Затем, используя индекс, я могу использовать итератор #times, чтобы поместить букву #в нижний регистр-d в строку сегмент. В Ruby я могу объединять строки с помощью метода #push (‹‹).
- После завершения сегмента я могу вставить сегмент в ответ. Это продолжается до тех пор, пока я не достигну конца исходной строки.
— наконец, я возвращаю переменную answer, соединенную дефисом.
Решение №3 с использованием JavaScript
function accum(s) { var answer = [] s.split("").forEach( (letter, idx) => { var segment = "" segment += letter.toUpperCase() while (idx > 0 ){ segment += letter.toLowerCase() idx -= 1 } answer.push(segment) }) return answer.join("-") }
Пошаговая инструкция (аналогично решению №2):
- Объявите переменную answer для сохранения результатов и вывода позже. Он будет храниться в виде массива.
. Как и в Ruby, в JavaScript есть функция #split, которая работает со строками для разделения символов. Затем я хочу перебрать каждый символ с помощью функции #forEach. Я могу передать букву и индекс, letter и idx соответственно.
- В каждом цикле я объявляю переменную segment для хранения строка
— первый символ, который нужно объединить в сегмент, — это заглавная буква с использованием toUpperCase(). В отличие от Ruby, я не могу вставлять подстроки в строки, поэтому мне нужно конкатенировать с помощью +=.
- Затем у меня есть итератор, если idx больше нуля, я буду конкатенировать букву в segment idx-times.
— После завершения цикла, если он вообще выполняется, я использую push(), чтобы сегментировать в массив answer.
- В JavaScript мне нужно явно использовать ключевое слово return, чтобы дать ответ, соединенный тире.
Практика №2
The goal of this exercise is to convert a string to a new string where each character in the new string is ‘(‘ if that character appears only once in the original string, or ‘)’ if that character appears more than once in the original string. Ignore capitalization when determining if a character is a duplicate. "din" # "(((" "recede" # "()()()" "Success" # ")())())" "(( @" # "))(("
Решение №1 с Ruby
def duplicate_encode(word) answer = "" count = Hash.new(0) word.each_char { |letter| count[letter.downcase] += 1} word.each_char { |letter| count[letter.downcase] == 1 ? answer << "(" : answer << ")" } answer end
Пошаговая инструкция:
– объявите ответ, чтобы сохранить результаты и вывести их позже.
– объявить хэш count и d присвоить значениям значение по умолчанию с нулевым значением. Здесь будет храниться количество раз, когда символ появляется в слове.
– Первая итерация будет проходить через каждую букву слова, #в нижнем регистре ее, установить ее в качестве ключа в хэше count и добавьте единицу к количеству раз, которое оно появилось.
— Вторая итерация снова пройдёт слово. На этот раз он #прописывает букву и проверяет по хешу count, сколько раз она появлялась. Если он появился один раз, я вставлю «(» в строку ответа, иначе вставлю «)». Я использую однострочный оператор if-else, так как требуется только одно действие.
— В конце я неявно возвращаю строку answer.
Решение № 2 с Ruby
def duplicate_encode(word) word.each_char.map { |letter| word.downcase.count(letter.downcase) == 1 ? "(" : ")" }.join end
Пошагово:
- Все это записывается одной строкой
- Чтобы исключить необходимость хранения ответа, я могу использовать метод #map для возврата нового массива . Я разбиваю слово по символам и сопоставляю его, передавая букву.
— С каждой буквой я буду использовать #count, чтобы узнать, сколько раз оно встречается в слове. Так как это должно быть нечувствительным к регистру, мне нужно #уменьшить регистр всего слова перед использованием #count.
- Затем мне нужно также #перевести в нижний регистр переданную букву. Если она появится один раз, я создам "(" в новом массиве из # сопоставить, иначе я создам ")" в новом массиве.
- В конце я #объединю вновь сопоставленный массив
Решение №3 с JavaScript
function duplicateEncode(word){ var count = new Object for (i = 0; i < word.length; i++ ){ var letter = word[i].toLowerCase() if (count[letter]){ count[letter]++ } else { count[letter] = 1 } } return word.split("").map( (char) => { if (count[char.toLowerCase()] === 1){ return "(" } else { return ")" } }).join("") }
Пошагово (аналогично решению №1):
- Объявите переменную count, которая является объектом.
- Пройдите через все слово один раз, используя цикл for.
- Для каждого символа в i-й индексируем его toLowerCase() и устанавливаем как переменную буква.
- Если объект count имеет букву в качестве ключа, я увеличу его на единицу, иначе установлю букву в >count и установите значение равным единице.
- Javascript содержит функцию map(), и мне придется явно возвращать результаты.
- Для каждого char, если count[char] равен единице, я верну в этот вновь сопоставленный массив «(», иначе «)».
- В конце мне нужно join() отображать массив с помощью “”.