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 функциясының жолын сіз оны жасайтын жолмен қолданатын болар еді. Егер сіз regex-ді пайдаланғыңыз келсе, жолды тек бір рет қолдануға болады деген жазуды жаза аласыз.
қосылды автор onit, көзі
G_H - Бақытымызға орай, үй тапсырмасы емес. Мен JAVA-ды өзімнің жеке кітаптармен және форумдармен оқуға тырысатын бастаушы әзірлеушімін.
қосылды автор Rich, көзі
Мэтт - Сіз кодты қате оқи алмайсыз. Мен жолдың ұзындығын тексеру тәсілін қолдануға тырысып, оны көшірмелердің санымен салыстыруға тырысып, айырмашылық бірегей таңбалардың саны болар еді. Бірақ, қазірдің өзінде бұл өте төмен болып көрінеді.
қосылды автор Rich, көзі

3 жауаптар

Сіз онда өте көп. String ішіне индекстеу үшін i индексін қолдануға және charAt (int) .

Әрбір таңбаның пайда болу санын қадағалау үшін деректер құрылымын қажет етеді. Бұл үшін HashMap пайдалануды ұсынамын, онда карта пернесі сіз оқыған Таңба және картаның мәні integer санының санын білдіреді оқиғалар.

6
қосылды
@Rich Ол өте анық. Мұнда ол түсінбеді, сондықтан ол мысал сұрайды ???
қосылды автор Android Killer, көзі
@Rich: Мүмкін жақсы (сіздің түсінуіңіз үшін) кодты жазуға бірінші рет тұрсаңыз, содан кейін жаңа сұрақ қойсаңыз немесе жаңартсаңыз, кез-келген проблеманы сипаттаңыз. HashMap-тегі хикая, егер сіз берілген таңба үшін ешқандай салыстыру болмасаңыз, жазба қосасыз: -> 1. Алайда, егер салыстыру бар болса, жазба қосасыз: -> мәні.
қосылды автор Adamski, көзі
Бұл дәл осылай ұсынамын.
қосылды автор Brandon Buck, көзі
Мүмкіндігіңізге мысал келтіріңізші. Мұндай көзқарас менің қалағандай көрінеді.
қосылды автор Rich, көзі
private boole isFormatValid (жол парольі) {int length = inputStr.length (); int numberChars = 0; (int i = 0, i <�ұзындығы; ++ i) {int index = password.indexOf (i); CharArray [i] = charAt (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 айнымалысын жасаудың қажеті жоқ). charAt() және length() сияқты CharSequence әдістеріне қоңырау шала аласыз password айнымалы Пароль 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-нің кез-келген шеберлігімен беделге ие, бірақ бұл жағдайда бұл әсіресе айтарлықтай (және таңқаларлық). мәселелерін шешуге мүмкіндік бермеген жағдайда деген кодты жазуды қалайсыз? Бірақ бұл әрдайым жаман емес; regex көмегімен бір жолды шешім:

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

Яғни, барлық көшірмелерді алып тастаңыз және алынған жолдың ұзындығы бірегей таңбалар саны сияқты бірдей. Дегенмен, жиынтыққа негізделген шешім әлі қарапайым. бұл қысқа.

1
қосылды
жақсы шешім. Рақмет
қосылды автор V. Kalyuzhnyu, көзі
Бірнеше ұпайлар: Егер сіз бірегейChars өлшемі бар болса, барлық цикл арқылы итерациядан гөрі ерте циклден шығуға болады. Сіз осы жағдайда HashSet-ді бастапқы 3 сыйымдылығымен жасай аласыз.
қосылды автор Adamski, көзі
Бұл үлкен түсініктемелермен өте пайдалы болды. Мен дәл қазір атып тастаймын.
қосылды автор Rich, көзі