Вариант решения с циклом, с алгоритмом фактически описанным в ответе @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();
}