Mock Exam 4 / Title Search

Здравейте,

Много се измъчих с тази задача и кодът ми дава правилни отговори за тест кейсовете, които са дадени в условито. Обаче като пусна в джъдж и ми дава на повечето wrong answer и само 10 точки. По долу си пускам кода ако някой може да ми каже къде греша.
Благодаря предварително!

StringFinder - Pastebin.com
Eдната грешка е IndexOutOfBounds : Във вътрешния цикъл, когато проверявате дали input.charAt(index) == result.charAt(j), трябва също така да проверите дали индексът е в границите на input.length(). В противен случай може да се получи изключение IndexOutOfBoundsException, когато индексът надхвърли дължината на входния низ. Можете да добавите допълнително условие към оператора if, за да проверите това

:if (index < input.length() && input.charAt(index) == result.charAt(j)) {
    sequence += String.valueOf(input.charAt(index++));
}

Изтриване на символи: Когато изтривате символи от резултата StringBuilder, трябва да коригирате променливата на цикъла k, за да отчетете премахнатия символ. След като изтриете символ с индекс k, трябва да намалите k с 1, за да избегнете прескачането на следващия символ. Можете да модифицирате вътрешния цикъл по следния начин:

for (int k = 0; k < result.length(); k++) {
    if (sequence.charAt(j) == result.charAt(k)){
        result.deleteCharAt(k);
        k--; // Decrement k after deletion
        break;
    }
}

Благодаря за отговора, но не това е проблемът.

Този код (1) спира да търси знак за премахване веднага щом открие първото срещане. Този код (2) проверява дали всеки знак от въведения низ се появява в думата, независимо от реда.

С долния цикъл (1) итерираш всеки знак в низа и за всеки знак влизаш в друг цикъл, който преминава през низа с резултати. Веднага след като намериш съвпадение за текущия символ, го премахваш и излизаш от вътрешния цикъл с break. Това означава, че премахваш първото срещане, което намериш, и след това спираш да търсиш други срещания.

for (int j = 0; j < sequence.length(); j++) {
    for (int k = 0; k < result.length(); k++) {
        if (sequence.charAt(j) == result.charAt(k)){
            result.deleteCharAt(k);
            break;
        }
    }
}

Ето как би трябвало да изглежда:

for (int j = 0; j < result.length(); j++) {
    if (index < input.length() && input.charAt(index) == result.charAt(j)) {
        index++;
        result.deleteCharAt(j);
        j--;
    }
}

В новия цикъл проверяваме всеки знак от резултата, за да видим дали съвпада с текущия знак от входа:

index < input.length() && input.charAt(index) == result.charAt(j)

Ако това стане, увеличаваме индекса и изтриваме знака на текущата позиция в резултата.

След това:

result.deleteCharAt(j)

премахва знака от резултат при текущия индекс j. Това премахва съвпадащия знак и само първото срещане, тъй като излизаме от цикъла към следващия символ на въвеждане след всяко съвпадение.

j–;

Това противодейства на ефекта на j++ във for-цикъла, когато знак бъде премахнат. Когато премахнем знак, всички знаци отдясно се изместват наляво и без j–, следващият знак ще бъде пропуснат в следващата итерация.

По този начин редът на знаците се поддържа и всеки съответстващ знак се премахва, решавайки проблемите, присъстващи в оригиналния код.

С пърция цикъл (2) преминаваш през всеки знак в резултата и проверяваш дали съвпада с текущия знак във входния низ. Ако има съвпадение, го добавяш към последователността и преминаваш към следващия знак във входния низ. Това се случва независимо къде се появява съответстващият знак в резултата. И ако знаците във входния низ се появят в резултата, но в различен ред, то пак ще го считаш за съвпадение.

for (int j = 0; j < result.length(); j++) {
    if (input.charAt(index) == result.charAt(j)){
        sequence += String.valueOf(input.charAt(index++));
    }
    if (index > input.length() - 1){
        break;
    }
}

Или целия код: TitleSearch - Pastebin.com.

Много е полезно да се правят и такива търсения: telerik title search - Google Suche.

Благодаря много за подробното обяснение! Разбрах какъв ми е бил проблемът.

1 Like

беше полезен този отговор