Первая часть моей серии статей для начинающих о структурах данных и алгоритмах. В этой статье я собираюсь ответить на вопрос, который должен быть приятным и простым для начала: переворот строки.

Заявление об ограничении ответственности: весь код будет написан на JavaScript, но я буду уделять больше внимания логике, чтобы этот блог по-прежнему можно было применять на других языках программирования.

Во введении к этой серии статей я говорил о том, что хочу сразу погрузиться в сложность среды выполнения. Поразмыслив над этой концепцией некоторое время, я понял, что попытка понять сложность времени выполнения будет ужасно трудной без какого-либо опыта решения некоторых из этих типов проблем в первую очередь. Итак, в этом блоге я собираюсь начать с очень простого вопроса для новичков, который поможет сдвинуть дело с мертвой точки. Не стесняйтесь опробовать решения, создав функцию в консоли разработчика Google Chrome, создав строку, а затем вызвав функцию со строкой в ​​качестве аргумента.

Давайте начнем!

Обращение строки - один из наиболее часто задаваемых вопросов для начинающих об алгоритмах, и хотя он может не часто появляться на технических собеседованиях, это хороший способ начать работать с алгоритмами в целом:

Для данной строки напишите функцию, которая будет вводить строку, а затем перевернуть эту строку. Например, «Hello world!» При вводе в функцию вернет «! Dlrow olleH».

Есть три разных способа решить эту проблему.

Решение 1

Я начинаю с объявления пустой строки и вызываю ее reversedString. reversedString будет использоваться для хранения каждого символа строки, заданной в качестве аргумента. Затем я перебираю каждый символ данной строки, используя оператор for..of. В документации MDN оператор for..of создает цикл, который выполняет итерацию по любому итерируемому объекту. В этом случае он будет перебирать каждый символ в данной строке. Вторая часть цикла for..of - это оператор, который будет выполняться для каждого итерируемого объекта, поэтому действие, которое будет выполняться для каждого символа строки.

Логика этого решения заключается в добавлении каждого символа данной строки в начало reversedString. По завершении цикла я возвращаю reversedString. Важно всегда возвращать конечный результат вашего решения.

Давайте рассмотрим код с примером строки «Hello world!». Сначала объявляется reversedString, но это пустая строка. Теперь для каждого символа в «Hello world!» Я собираюсь добавить его перед reversedString и его содержимым. Первая итерация изменит пустую строку reversedString на «H». Во второй итерации впереди будет добавлен следующий символ, в результате чего получится «eH». Третий сделает «лех» и так далее, и тому подобное.

Решение 2

Это решение требует некоторого фундаментального понимания встроенных методов JavaScript и поэтому может быть неприменимо в других языках программирования. В этом решении я использую методы обратного, разбиения и соединения. Конечно, вы всегда можете обратиться к документации MDN для получения дополнительной информации об этих методах, но я также кратко рассмотрю каждый из них здесь. Обратный метод не требует пояснений - он принимает массив и меняет его содержимое на противоположное. Ключевое отличие здесь в том, что он принимает массив, в то время как нам предоставляется строка, так как же нам это изменить?

Метод разделения - тот, который нам нужен. Он принимает аргумент строки и разбивает его на подстроки для каждого символа в строковом аргументе. Таким образом, строка «Hello» будет разбита на массив как таковой: [‘H’, ‘e’, ‘l’, ‘l’, ‘o’]. После использования split для строки мы можем затем использовать обратный метод для этого массива. В этом случае массив из нашего примера будет преобразован в [‘o’, ‘l’, ‘l’, ‘e’, ‘H’]. Следующим шагом будет преобразование массива обратно в строку. Здесь можно использовать метод соединения. Метод соединения принимает аргумент массива, затем создает и возвращает новую строку, объединяя все элементы в массиве. Использование соединения в обратном массиве в нашем примере вернет нам «olleH».

Наконец, не забудьте вернуть измененную строку!

Решение 3

Третье решение также требует использования вспомогательного метода. В частности, вспомогательный метод массива reduce. Метод reduce принимает два отдельных аргумента. Первый аргумент - это стрелочная функция, а второй аргумент - начальное начальное значение для функции. Внутри стрелочной функции он принимает аккумулятор и текущее значение. Учитывая два аргумента, он затем выполнит итерацию по массиву и выполнит указанное действие для каждого итерируемого объекта и заменит текущее значение, в конечном итоге вернув одно значение. Например, с массивом [1,2,3,4], используя для него сокращение и указав, что каждое последующее значение будет добавляться к текущему значению, мы получим решение 10.

Чтобы прояснить любую путаницу, неопределенное значение во второй строке является результатом объявления массива в первой строке, поскольку любое объявление неявно ничего не вернет. Еще одно важное замечание: после currentValue у меня остается пустое место. Это второй аргумент, который является начальным начальным значением. Если бы я изменил это значение на 10, наш ответ был бы равным 20, поскольку мы начинаем с 10, а затем добавляем каждый элемент в массив к 10. Есть также еще один сценарий, который я счел важным обсудить. Раньше я совершил глупую ошибку, вставив пустую строку вместо пробела в качестве начального начального значения, в результате чего результат стал «1234».

Это больше связано с приведением типов в JavaScript. Хотя это довольно запутанная тема, идея в этом примере заключается просто в том, что, поскольку я начал исходное значение как строку, JavaScript заставит целые числа в данном массиве также стать строкой при добавлении к текущему значению. В JavaScript добавление двух строк просто ставит их рядом, поэтому добавление строки «1» и строки «2» даст «12».

Итак, как мы можем использовать сокращение для нашего «Hello world!» нить? Идея аналогична предыдущему решению, в котором мы должны сначала превратить нашу строку в массив, используя метод split, а затем используя для этого метод reduce. Ключевым отличием при возврате перевернутой строки является то, что мы добавляем каждый символ в начало текущего значения, поэтому в данном случае это reversedString.

Надеюсь, это имеет смысл, но не стесняйтесь попробовать это и поиграть с методом уменьшения, так как к нему нужно привыкнуть!

И последнее, но не менее важное: всегда не забывайте возвращать перевернутую строку. Я упоминаю об этом еще раз, потому что не могу сосчитать, сколько раз я был сбит с толку, почему я ничего не получаю, только для того, чтобы понять, что я никогда не просил вернуть значение.

Комментарии

Итак, вот три различных способа решения проблемы переворачивания струны. Бывают случаи, когда интервьюеры могут попросить вас не использовать вспомогательный метод, так как это может значительно облегчить получение решения. В этом случае решение перебора символов может сработать. Все также понимают концепции с разной скоростью, поэтому некоторым людям может быть легче понять одно решение, чем другим.

В своем следующем блоге я собираюсь заняться обращением целых чисел. Хотя стратегия очень похожа, работа с целыми числами может вызвать некоторые интересные проблемы. Вот проблема на следующей неделе. Если хотите, попробуйте решить эту проблему самостоятельно!

Для целого числа напишите функцию, которая будет принимать на входе целое число, а затем менять его местами. Например, «-321» при вводе в функцию вернет «-123», а «82» вернет «28».