Java - Як перевірити дублікати символів у рядку?

Мені потрібно написати функцію, яка перевіряє рядок для повторюваних значень і повертає кількість унікальних символів. Якщо граф більше 3, він повинен повертати істину. Якщо кількість менше 3, це має бути хибним. Ось що я намагався (помічаю, я новачок у java)

private boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    int numberDups = 0;

    for(int i=0; i < length; ++i) {
        Pattern pattern = Pattern.compile("(.)(?=.*?\1){1,20}");
        Matcher matcher = pattern.matcher(inputStr);
        numberDups += 1;
    }
    if (numberDups < 3) {
        return false;
    }
    return true;
}

Я намагався використовувати регулярний вираз, оскільки було запропоновано, що це може бути простіше. Але якщо я зможу виконати це без регулярного виразу, я буду щасливішим.

Це що означає?

private boolean isFormatValid(String password) {
    int length = inputStr.length();
    int numberChars = 0;

    for(int i=0; i < length; ++i) {
                int index = password.indexOf(i);
        CharArray[i] = charAt(i);   
    }
}

Я відчуваю, що це навіть не близьке до правильного ...

4
Питання запитує про кількість унікальних символів, але код, схоже, намагається підрахувати дублікати .... Я просто читаю це неправильно ??
додано Автор Matt Fenwick, джерело
Я б просто цикл і використовувати рядки indexOf функцій, як ви це робите. Якщо ви хочете використовувати регулярний вираз, ви можете написати регулярний вираз, який потрібно використовувати лише один раз.
додано Автор onit, джерело
G_H - На щастя, це не домашнє завдання. Я розробник-початківець, який намагається самостійно вивчати JAVA з деякими книгами та форумами.
додано Автор Rich, джерело
Метт - Ви не читаєте код неправильно. Я намагався використати підхід перевірки довжини рядка та порівняння його з кількістю дублікатів, а різниця - кількість унікальних символів. Але це здається надто складним зараз, коли воно вниз.
додано Автор Rich, джерело

3 Відповіді

Ви дуже там. Замість того, щоб використовувати регулярний вираз, ви можете використовувати індекс: i для індексування в String і читати певний символ за допомогою charAt (int) .

Потім вам потрібна структура даних для відстеження кількості подій кожного символу. Я пропоную використати для цього HashMap , за допомогою якого ключ картки - це прочитаний Character , а значення карти є підрахунком числа Integer випадків виникнення.

6
додано
@Rich Він досить ясно. Що ви не зрозуміли тут, так що ви просите приклад ???
додано Автор Android Killer, джерело
@Rich: Напевно, краще (для вашого розуміння), якщо у вас перший удар по написанню коду, а потім опублікуйте нове запитання або оновіть його, описуючи будь-які проблеми, які ви зіткнулися. Хитрість з HashMap полягає в тому, що, якщо для певного символу не буде віднесено зображення, ви додасте запис: -> 1. Однак, якщо вже існує відображення, ви додаєте запис: -> .
додано Автор Adamski, джерело
Це саме те, що я збираюся запропонувати.
додано Автор Brandon Buck, джерело
Не могли б ви навести приклад того, що ви маєте на увазі. Цей підхід схоже на те, що я хочу.
додано Автор Rich, джерело
приватний логічний isFormatValid (String пароль) {int length = inputStr.length (); int numberChars = 0; for (int i = 0; i
додано Автор Rich, джерело

Алгоритм дуже простий:

  1. Розбити рядок на масив символів
  2. Додайте всі ці символи до Set (HashSet).

Після цього ваш набір містить лише унікальні символи.

3
додано
Скажіть, якщо я помиляюся, це питання - це функція, яка перевіряє рядок для повторюваних значень, а повертає кількість унікальних символів "
додано Автор mishadoff, джерело
Однак не допоможе підрахувати випадки. Виявляється, лише якщо є копії символів.
додано Автор G_H, джерело
@mishadoff Ви маєте рацію ... Я зосереджував надто багато уваги на коді. Він дійсно попросив кількість унікальних персонажів. +1 в цьому випадку.
додано Автор G_H, джерело
Я дивлюся на цю пропозицію зараз. G_H - Це саме те, що я хочу зробити.
додано Автор Rich, джерело

Я думаю, що змінна numberDups у вашому прикладі коду неправильно називається, і це заплутує деяких людей. Ця змінна повинна представляти кількість символів різних , чи не так? Тобто, якщо рядок abcabc , номер буде 3 , а для рядка aaaaaaaaa він буде 1 .

That being the case, the simplest solution is, as others have said, to use a Set. In fact your code is almost there; just get rid of that numberDups counter and replace it with a HashSet, like so:

static boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    Set uniqueChars = new HashSet();

    for(int i=0; i < length; ++i) {
        uniqueChars.add(inputStr.charAt(i));
    }

    return uniqueChars.size() >= 3;
}

(Тим не менше, вам не потрібно створювати змінну inputStr . Ви можете зателефонувати за допомогою методів CharSequence, таких як charAt() і length() на password , оскільки String реалізує інтерфейс CharSequence .)


EDIT: I also want to point out that, the way you were using the Pattern and Matcher, you weren't using them. You correctly created the Matcher from the Pattern, and associated it with the input string, but then it just sat there. In order to apply the regex, you have to call one of the methods, find() or matches() (or lookingAt(), but nobody ever uses that one).

Це дуже поширена помилка початківця. Java має репутацію надмірно багатослівного в будь-якому випадку, але це особливо помітно (і дивовижно) у цьому випадку. Я маю на увазі, що означають регулярні вирази, якщо не дозволяють вам вирішити проблеми без пишучих кодів? Але це не завжди так погано; Ось однострокове рішення з використанням регулярного виразу:

return inputStr.replaceAll("(.)(?=.*\\1)", "").length() >= 3;

Тобто, видаліть усі дублікати, а довжина результуючого рядка така ж, як і кількість унікальних символів. Рішення на базі набору все ще простіше, однак; цей лише коротший.

1
додано
гарне рішення. Дякую
додано Автор V. Kalyuzhnyu, джерело
Пара балів: Ви можете вийти з циклу рано, якщо uniqueChars має розмір: 3, а не повторювати через всю Стрічку. Ви можете створити свій HashSet з вихідною ємністю 3 у цьому випадку.
додано Автор Adamski, джерело
Це було дуже корисно з великими поясненнями. Я збираюся дати йому удар прямо зараз.
додано Автор Rich, джерело
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників