Java - Как проверить наличие дублирующихся символов в строке? - PullRequest
4 голосов
/ 28 октября 2011

Мне нужно написать функцию, которая проверяет строку на наличие дублирующихся значений и возвращает количество уникальных символов. Если число больше 3, оно должно вернуть true. Если число меньше 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);   
    }
}

Я чувствую, что это даже близко к тому, чтобы быть правым ...

Ответы [ 3 ]

6 голосов
/ 28 октября 2011

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

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

3 голосов
/ 28 октября 2011

Алгоритм очень прост:

  1. Разделить строку на массив символов
  2. Добавьте все эти символы в Set (HashSet).

После этого ваш набор содержит только уникальные символы.

1 голос
/ 28 октября 2011

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

В таком случае самое простое решение, как уже говорили другие, использовать Набор. На самом деле ваш код почти там; просто избавьтесь от счетчика numberDups и замените его на HashSet<Character>, например:

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

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

    return uniqueChars.size() >= 3;
}

(Однако вам не нужно создавать переменную inputStr. Вы можете вызывать методы CharSequence, такие как charAt() и length() для переменной password, поскольку String реализует интерфейс CharSequence.)


РЕДАКТИРОВАТЬ: Я также хочу отметить, что, как вы использовали Pattern и Matcher, вы не использовали их. Вы правильно создали Matcher из Pattern и связали его с входной строкой, но затем он просто сидел там. Чтобы применить регулярное выражение, вы должны вызвать один из методов, find() или matches() (или lookingAt(), но никто никогда не использует его).

Это очень распространенная ошибка новичка. Java имеет репутацию чрезмерно многословного в любом случае, но это особенно заметно (и удивительно) в этом случае. Я имею в виду, для чего нужны регулярные выражения, если не позволить вам решить проблемы без написания пакетов кода? Но это не всегда так плохо; Вот решение с одной строкой, использующее регулярное выражение:

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

То есть удалите все дубликаты, и длина полученной строки будет равна количеству уникальных символов. Решение на основе множеств все же проще; этот просто короче.

...