Как найти самое длинное слово в строке с учетом знаков препинания в Kotlin
Что проверяют
Умеете ли вы уточнить, что считать словом, и знаете ли, как регулярные выражения на JVM ведут себя с кириллицей. Следом обычно спрашивают про крайние случаи: пустая строка, несколько слов одинаковой длины, дефисы и апострофы.
Как отвечать
Сначала задайте вопросы, от которых зависит код: «из-за» и «Нью-Йорк» это одно слово или два, считаются ли числа словами, что вернуть на пустой строке и какое слово выбрать при равной длине.
Дальше надёжнее искать сами слова, а не резать строку по перечисленным знакам препинания:
fun longestWord(s: String): String? =
Regex("""[\p{L}\p{N}]+(?:['-][\p{L}\p{N}]+)*""")
.findAll(s)
.map { it.value }
.maxByOrNull { it.length }\p{L}и\p{N}: любые буквы и цифры Unicode, кириллица и латиница работают одинаково;- необязательная группа: пропускает дефис или апостроф только внутри слова, а не на краю;
maxByOrNull: при равной длине возвращает первое слово, на пустом вводеnull, это стоит проговорить;findAll: лениваяSequence, промежуточный список не создаётся.
Альтернатива без регулярки: один проход по строке с Char.isLetterOrDigit(), где вы запоминаете начало текущего слова и лучшую пару «начало, длина». Это O(n) без лишних аллокаций, главное не забыть проверить слово, которым строка заканчивается.
Оба варианта линейные. Тесты назовите сразу: пустая строка, одни знаки препинания, слово в самом конце, одинаковые длины, смесь кириллицы и латиницы.
Где спотыкаются
Режут строку по \W+. В регулярках Java и Kotlin на JVM \w по умолчанию означает только латиницу, цифры и подчёркивание, и русский текст разваливается целиком. Нужен флаг (?U) или классы \p{L}.
Перечисляют знаки вручную и забывают про длинное тире, ёлочки, многоточие и неразрывный пробел. Такие символы прилипают к слову и увеличивают его длину.
После split не убирают пустые строки, которые появляются при знаке препинания в начале или конце. Для поиска максимума это безвредно, но стоит задаче смениться на «самое короткое слово» или «все слова», и ответ станет неверным.