Найти первый символ в первом максимально длинном слове с четным числом символов в строке
Написал, программу по следующему ТЗ:
Найти первый символ в первом максимально длинном слове с четным числом символов в строке. В строке указываются только слова, разделенные одним или несколькими пробелами.
При тестовых данных:
1234 4567 23456789
Выводит результат: 4
Хотя по логике описанной в тз, должна вывести 2. Т.К число 23456789 - первое максимально длинное слово, а так же количество символов в нем четное.
Кто подскажет в чем может быть проблема?
UPD: Забыл добавить, алгоритм должен быть реализован максимально оптимизированно по быстродействию т.е нельзя использовать такие функции как(split,filter и т.д) Так же нельзя использовать списки.
fun main()
{
var s = readLine();
var word = "";
var max = 0;
var s2 = "";
if(s!=null)
{
for(c in s)
{
s2+=c;
println(s2);
if(c.toInt() == 32)
{
var b = s2.length;
var s3 = s2;
s2="";
if((b-1 > max) && ((b-1) % 2 == 0))
{
max = b-1;
word = s3;
//println(word);
//println(max);
}
}
}
if(word != "")
{
println(word[0]);
}
else
{
println("Слов кратных двум не было.")
}
}
}
Ответы (4 шт):
4 и 2 - неверные ответы. Верный ответ - 1.
По условию, во-первых, количество символов в слове должно брать четным. А в 2345678 нечетное количество. А во-вторых, ищется первый символ из первого найденного слова, удовлетворяющего условиям. И это слово 1234.
PS. В котлине у строк есть метод split(), который сразу разделит строку по словам.
val input = "1234 4567 2345678"
val output = input.split(" ")
.filter { word -> word.length > 0 && word.length % 2 == 0 }
.maxBy { word -> word.length } !![0]
println(output)
Маленькая машина состояний.
Вначале состояние 0.
MaxLen = 0
Идёте по строке.
Встретили не пробел в состоянии 0 - изменили состояние на 1, запомнили символ, запомнили позицию.
Встретили пробел в состоянии 1 - изменили состояние на 0, вычислили разность с запомненной позицией, если она чётная и больше MaxLen - скопировали запомненный ранее символ в результат. То же самое - при достижении конца строки.
В остальных случаях ничего не делается.
Данный код, вроде бы, решает Вашу задачу:
private val Int.isEven //Extension свойство для Int, проверяет четность числа через битовое И
get() = and(1) != 1
private fun getFirstLetterOfBiggestWordWithEvenLettersNumber(text: String): Char {
var length = 0 // Сколько букв в слове, по которому идём сейчас
var maxLength = 0 // Насколько длинным было самое длинное слово из пройденных раньше (вообще, учитываться будут только слова с четным числом букв)
var lastWordBegin = '-' // С какой буквы началось слово, по которому бежим сейчас
var result = '-' // Здесь храним ответ
for (letter in text) { // Для каждой буквы текста
if (letter == ' ') { // Если это пробел
if (length.isEven && length > maxLength) { // Если в слове было четное число букв и оно самое длинное из найденных
maxLength = length // Запоминаем длину
result = lastWordBegin // Запоминаем первую букву закончившегося слова как ответ
}
length = 0 // Слово кончилось
continue // Переходим к следующей букве
}
if (length == 0) lastWordBegin = letter // Запоминаем первую букву нового слова
length++ // Длина текущего слова увеличилась на 1
}
if (length.isEven && length > maxLength) result = lastWordBegin // В конце текста не будет пробела, так что проверим последнее слово
return result
}
Ну и комментарий по поводу Вашего стиля кода. Старайтесь давать говорящие имена всем функциям, методам, переменным и классам, иначе даже после перерыва в виде выходных Вам самому будет очень сложно разобраться в своем коде. Ну и когда работать пойдете - Вас убьют за некрасивые имена переменных куда скорее, чем за алгоритмы:)
P.s. Хорошая проверка - если Вы назвали что-то именем короче 8 символов, то это уже повод задуматься. (не относится к итераторам в циклах (i,j) и координатам (x,y,z) из математики)