Проверка пароля на совпадение подряд идущих символов
Мне необходимо проверить есть ли в пароле, вводимом пользователем повторение ПОДРЯД идущих символов в количестве, введенном в переменную maxRepeats. То есть если maxRepeats 2, то пароль может иметь вид pasword, password, passsword и не более. Чет я тут встрял. Необходимо решить одинарным циклом.

Ответы (2 шт):
Проходите по строке начиная со 2 символа и поддерживаете счетчик повторений.
На каждой итерации сравниваете символ с предыдущим.
Если символ не совпадает - обнуляете счетчик.
Если совпадает - увеличиваете счетчик повторений и сравниваете с maxRepeats.
Если счетчик повторений стал больше разрешенного - значит условие нарушено (повторений символа больше).
Получается подсчет повторений за 1 проход.
Вариант решения с циклом, с алгоритмом фактически описанным в ответе @DmitryK:
public boolean verify(String password) {
int n = password.length();
if (n < minLength) {
return false;
}
for (int i = 1, count = 1; i < n; i++) {
if (password.charAt(i) == password.charAt(i - 1)) {
if (++count > maxRepeats) { // количество повторов превысило лимит
return false;
}
}
else {
count = 1; // сброс счётчика символов
if (maxRepeats >= n - i) {
break; // отбросить проверку конца строки
}
}
}
return true; // длина не превышена
}
Также для решения подобного рода задач можно использовать регулярные выражения и метод String::matches:
public boolean verify(String password) {
if (password.length() < minLength) {
return false;
}
return !password.matches(".*(.)\\1{" + maxRepeats + ",}.*");
}
".*(.)\\1{" + maxRepeats + ",}.*":
.*пропустить символы в начале и конце и строки(.)\\1{" + maxRepeats + ",}- найти любой символ(.), после которого идёт аналогичный со ссылкой на обнаруженный ранее\\1, в количестве как минимумmaxRepeats
Или же более производительный вариант c использованием Matcher::find:
public boolean verify(String password) {
return !Pattern.compile("(.)\\1{" + maxRepeats + ",}").matcher(password).find();
}