(переписано с учетом уточняемого вопроса.)
Насколько я понимаю, строка должна содержать целые числа, чередующиеся с символами, и нам нужно наибольшее целое число, за которым следуетпо "+".
Я бы подошел к этому, разделив строку на слова, а затем посмотрев на пар слов.Мы можем сделать это с помощью функции zipWithNext()
, которая выдает список всех соседних пар.Затем мы можем filter()
выбрать только те, в которых второе слово равно "+", mapNotNull()
, чтобы преобразовать первое слово такой пары в Int
, где это возможно (игнорируя null
s из тех, которые неt действительные целые числа) и возьмите max()
из этих чисел.(Если их нет, max()
возвращает null
, поэтому мы можем вместо этого использовать оператор Элвиса для замены -1.)
fun String.bestHighJump()
= split(" ")
.zipWithNext()
.filter{ it.second == "+" }
.mapNotNull{ it.first.toIntOrNull() }
.max() ?: -1
(я сделал эту функцию расширения для String
, в основном потому, что кажется, что он хорошо подходит, он также избегает необходимости объявлять и затем использовать параметр. Но нормальная функция будет работать почти так же.)
Чтобы сделать это более идиоматичным, он бывероятно, лучше удалить оператора Элвиса и вернуть null
напрямую, если не было совпадений;это делает ситуацию более очевидной для вызывающей стороны, которая может затем решить, как обрабатывать этот случай.
Поскольку вы смотрите на регулярные выражения, вот альтернативное решение, использующее одно из них:
fun String.bestHighJump()
= Regex("""([0-9]+) [+]\B""")
.findAll(this)
.map{ it.groupValues[1].toInt() }
.max() ?: -1
Это на одну строку короче, но я думаю, что это намного менее понятно.По моему опыту, регулярные выражения часто трудно понять правильно, отладить и поддерживать, поэтому я предпочитаю другие подходы.(Для сравнения, первая версия сработала впервые, в то время как версия регулярного выражения потребовала много попыток!)
Здесь регулярное выражение соответствует одному успешному результату (одна или несколько цифр, за которыми следует пробел, +
изатем граница слова. (Последнее необходимо, потому что мы не знаем, является ли этот результат последним в строке, или за ним следуют другие. Регулярные выражения совпадают жадно, поэтому нам также не нужен один в начале.)
findAll()
ищет всю строку и возвращает последовательность совпадений, затем мы берем первую группу из каждой (которая является числом), преобразуем ее в целое число (нет необходимости обрабатывать недопустимые числа этовремя, если регулярное выражение работает), и возьмите максимум, как и раньше.
(Вопрос по-прежнему не ясен о том, как обрабатывать показатели успеха с несколькими символами. Я предполагаю, что мы хотим толькоподсчитывать результаты, где индикатором успеха является только один символ «+». Если мы также должны включить случаи, когда среди «%» и / или других символов есть «+», то оба функцииионы могут быть настроены для этого.Но опять же, регулярное выражение было бы сложнее сделать.)
Что касается того, где учить подобные вещи, я предполагаю, что вы уже знаете о Kotlin docs .(И я бы порекомендовал книгу Kotlin In Action для изучения языка.) Существуют разные подходы к обработке строк, в зависимости от ваших потребностей, поэтому их сложнее рекомендовать - но основные принципы не конкретныв Котлин, так что, вероятно, есть много мест, где можно посмотреть.И если у вас есть более сложный случай, вы всегда можете опубликовать его как еще один вопрос здесь!