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, крыніца
Matt - Вы не чытаеце код няправільна. Я спрабаваў выкарыстаць падыход праверкі даўжыні радка і параўнаць яго з колькасцю дубляў, і розніца будзе шэраг унікальных персанажаў. Але гэта здаецца занадта складаным зараз, што гэта ўніз.
дададзена аўтар Rich, крыніца

3 адказы

Вы вельмі шмат там. Замест таго каб выкарыстоўваць рэгулярны выраз, вы можаце выкарыстоўваць індэкс: я індэксаваць ў Радок і прачытаць канкрэтны сімвал, выкарыстоўваючы Шара (INT) ,

Затым патрэбна структура дадзеных для адсочвання колькасці уваходжанняў кожнага знака. Я прапаную выкарыстоўваць HashMap для гэтага чаго ключ карты з'яўляецца Сімвал вы прачытаеце і значэнне карты з'яўляецца Integer Падлік колькасці уваходжанняў.

6
дададзена
@Rich Ён даволі clear.What у не зразумеў, вось так у ¨R просяць прыклад ???
дададзена аўтар Android Killer, крыніца
@Rich: Напэўна, лепш (для разумення), калі ў вас ёсць першы ўдар у напісанні кода, а затым дадаць новы пытанне або абнавіць гэтую апісваюць любыя праблемы, якія працуюць у. Трук з HashMap у тым, што, калі няма адлюстравання для дадзенага сімвала вы дадасце запіс: <�сімвал> -> 1. Аднак, калі ўжо існуе адлюстраванне, можна дадаць запіс: <�сімвал> -> <�папярэдняя запіс значэнне + 1>.
дададзена аўтар Adamski, крыніца
Гэта менавіта тое, што я збіраўся прапанаваць.
дададзена аўтар Brandon Buck, крыніца
Не маглі б вы прывесці прыклад да таго, што вы маеце на ўвазе. Такі падыход гучыць як тое, што я хачу.
дададзена аўтар Rich, крыніца
прыватнае лагічнае isFormatValid (String пароль) {INT = даўжыня inputStr.length (); INT numberChars = 0; для (INT I = 0; я <�даўжыня; ++ я) {INT індэкс = password.indexOf (я); CharArray [I] = Шар (я); }}
дададзена аўтар Rich, крыніца

Алгарытм вельмі просты:

  1. Разбівае радок у масіў сімвалаў
  2. Дадайце ўсе гэтыя сімвалы Set (HashSet).

Пасля таго, што ваш набор змяшчае толькі унікальныя сімвалы.

3
дададзена
Скажыце мне, калі я памыляюся, пытанне было "функцыя, якая правярае радок для паўтаральных значэнняў і <�я> вяртае колькасць унікальных сімвалаў »
дададзена аўтар mishadoff, крыніца
Не дапаможа падліку уваходжанняў, хоць. Толькі выяўленне, калі ёсць якія-небудзь паўтараюцца сімвалы.
дададзена аўтар G_H, крыніца
@mishadoff Вы маеце рацыю ... Я занадта факусуюцца на кодзе. Ён сапраўды прасіў за колькасць унікальных персанажаў. +1 ў гэтым выпадку.
дададзена аўтар G_H, крыніца
Цяпер я гляджу на гэтую прапанову. G_H - Гэта менавіта тое, што я шукаю рабіць.
дададзена аўтар Rich, крыніца

Я думаю, што пераменная numberDups ва ўзоры кода няправільна названы, і гэта зман некаторых людзей. Гэтая пераменная павінна прадстаўляць лік розных сімвалаў, гэта не? Гэта значыць, калі радок abcabc лік будзе 3 і для радкі ааааааааа гэта будзе 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 як Шар() і даўжыня() на пароль пераменная, так як Радок які рэалізуе 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, а не перабіраць ўвесь String. Вы можаце стварыць свой HashSet з першапачатковай магутнасцю 3 у гэтым выпадку.
дададзена аўтар Adamski, крыніца
Гэта было вельмі карысна з вялікімі тлумачэннямі. Я збіраюся даць яму стрэлілі прама цяпер.
дададзена аўтар Rich, крыніца