В задачах на применение классических алгоритмов часто используют бинарный (двоичный) поиск. Его можно применять только на предварительно отсортированном массиве. Самый простой алгоритм сортировки см. в статье Пузырьковая сортировка.
Суть бинарного поиска можно описать как «разделяй и властвуй». Исходный отсортированный по порядку массив мы делим пополам и проверяем элемент посередине. Если он равен тому, который мы ищем, то возвращаем его индекс. Если не равен, то проверяем границы и выбираем ту половину, в которой искомый элемент может находиться и выполняем проверку снова. Так мы сужаем область поиска до тех пор, пока левая граница не станет равна правой. Если элемент не удалось найти, возвращаем -1.
Тэги: Java 11, алгоритмы, Kotlin.
Среди других алгоритмов сортировки «пузырьковая» является самой медленной. Однако при этом алгоритм достаточно прост для понимания. На практике вместо него используют другие алгоритмы сортировки. Про пузырьковую сортировку любят рассказывать при обучении программированию и любят спрашивать на собеседованиях.
Суть алгоритма заключается в том, что мы последовательно проходимся по массиву элементов, сравнивая текущий и предыдущий между собой. Если предыдущий больше текущего, то меняем их местами. Таким образом, элемент с наибольшим значением как бы «всплывает» в конец массива. Отсюда и название «пузырьковая сортировка».
Тэги: Java 11, Java, алгоритмы, файлы.
Во многих редакторах при работе с текстовым документом вы можете видеть, сколько всего строк содержится в этом файле. Строки между собой разделяются символом перевода строки, который в каждой операционной системе (Windows, Unix, Mac) свой.
Давайте разберёмся, как быстро подсчитать количество строк в текстовом файле независимо от той ОС, в котором выполняется наш код. Более того, текстовый файл может быть сколь угодно большим, поэтому мы будем использовать буферизацию потока, чтобы не израсходовать всю доступную оперативную память.
Предположим, наш метод принимает на вход абсолютный путь до целевого файла, а возвращает количество строк в виде целочисленного типа long. Рассмотрим две реализации.
Тэги: Java, алгоритмы, головоломки, Java 8.
Среди алгоритмических задач довольно часто встречается задача на проверку скобочной последовательности. То есть на вход передаётся строка, в которой содержатся символы скобок и, возможно, другие символы. И нужно ответить, правильно ли скобки вложены друг в друга или нет? Иными словами, на каждую открывающую скобку должна приходиться закрывающая скобка.
Практическим применением этой задачи может быть калькулятор, в котором пользователь вводит выражение для вычисления целиком. Также без такой проверки не обойтись при реализации простейшего интерпретатора.
Первое, что приходит в голову, это подсчитать количество открывающих и количество закрывающих скобок в строке и если эти числа равны, то считать, что последовательность скобок правильная. Возможно, это и будет работать в самых простых случаях, однако последовательность «(())» будет правильной, а последовательность «())(» – неправильной. При этом количество открывающих и закрывающих скобок у них одинаковы. Кроме того, скобки могут быть разных типов (круглая, фигурная, квадратная и т.п.) и скобки должны соответствовать ещё и по типу. Поэтому в основе такой проверки должна лежать работа со стеком.
Тэги: Java 11, алгоритмы, Java, файлы.
Контрольная сумма от набора байт позволяет убедиться в том, что данные на клиенте, полученные от сервера, являются корректными. Для этого вместе с файлом сервер может предоставлять контрольную сумму для проверки на клиентской стороне. Существует несколько алгоритмов вычисления контрольной суммы, рассмотрим самые популярные: md5, sha-256, sha-512 и crc-32.
В пакете java.security есть такой класс как MessageDigest. Он позволяет получить одну из встроенных реализаций алгоритма вычисления контрольных сумм. Поэтому сначала реализуем метод, который абстрагирован от конкретного алгоритма и работает с любым MessageDigest одинаково.
Тэги: Java, Java 8, Kotlin, алгоритмы.
При работе с датами часто бывает нужно получить последний день текущего месяца или года. Поскольку последний день года всегда равен 31 декабря, то мы можем напрямую создать эту дату с помощью метода LocalDate.of(). А вот последний день месяца зависит от конкретного месяца. Дней в месяце может быть 30 или 31, а для февраля и вовсе 28 или 29.
Чтобы не разбираться в логике работы календаря, начиная с Java 8 (а, значит, и в Kotlin) нам доступен специальный класс TemporalAdjusters. Он имеет несколько полезных методов, но в данном случае нас интересует lastDayOfMonth(), возвращающий специальный объект с интерфейсом TemporalAdjuster. Этот интерфейс содержит метод adjustInto(), который позволяет «выравнивать» любую переданную ему дату (или дату со временем) по определённому правилу. В нашем случае дата будет выровнена по последнему дню месяца.
Тэги: алгоритмы, Spring, Java.
MD5 хэш (Message Digest 5) – это 128 битный алгоритм вычисления хэша от сообщения произвольной длины. Чаще всего хэш вычисляется от строки (для проверки паролей) и от файла (для контроля его целостности).
Следует сразу же заметить, что хранение паролей в виде md5-хэшей в настоящее время считается небезопасным, т.к. md5-хэш довольно сильно подвержен коллизиям. Коллизией называется ситуация, когда у двух исходных сообщений хэши равны. То есть для успешного прохождения проверки пароля, сохраняемого в виде md5-хэша, вам даже не обязательно знать именно этот пароль. Достаточно знать пароль, имеющий такой же хэш. Более того, хэши от простых паролей можно напрямую искать в Google.
Алгоритм хэширования MD5 является частью стандартной библиотеки Java, поэтому вычислить хэш от строки (например, от пароля) достаточно легко.
Тэги: Java 8, алгоритмы, Stream API, файлы.
При работе с файловой системой может потребоваться вычислить размер папки (folder) с лежащими в ней файлами. Как известно, директория – это лишь логический раздел на файловой системе, поэтому её размер равняется сумме размеров всех файлов, находящихся внутри неё. При этом нужно пройтись по всей иерархии файлов и папок, находящихся внутри.
Сначала создадим объект папки с помощью метода Paths.get(). В него передадим полный путь до интересующей нас папки. Этот путь мы получаем в качестве параметра нашего метода.
При разработке приложений иногда бывает необходимо выбрать случайный элемент из некоторого множества. Предположим, что у нас есть список фруктов и нам нужно выбрать случайным образом один из них.
Сначала создадим генератор случайных значений SecureRandom. Можно также использовать и обычный Random, но первый выдаёт более случайные значения.
Тэги: головоломки, Java, алгоритмы.
Если перед вами встанет задача обменять значения двух числовых переменных a и b между собой, скорее всего, вы сделаете это так:
То есть поменять значения одновременно нельзя, ибо одно из них затрётся. Чтобы этого не произошло, мы создаём новую буферную переменную, куда и помещаем на время одно из значений.
А что, если нам нужно обменять значения числовых переменных между собой, не создавая новых переменных?
Kotlin, Java, Java 11, Java 8, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.