Странное / любопытное поведение в рекурсивной функции

1

Я пытаюсь запрограммировать функцию, проверяющую, является ли строка результатом набора действий в предыдущей строке. В частности, строка "b" представляет собой преобразование строки "a", если она соответствует одному и тому же порядку символов, имеет только одни и те же символы, но может быть умножена. Например: "aabba" - это преобразование "aba" но не "abaa", поскольку в конце оно имеет двойной 'a'.

Код выглядит следующим образом:

public static boolean isTrans(String s, String t)
{
    if(s.equals(t)){return true;} //obviously the latter is transformation
    else if(s.length()==0||t.length()==0){return false;} //either is empty, can't be transformation
    else if(s.charAt(0)!=t.charAt(0)){return false;} //obviously not transformation
    else {return (s.length()==(isTrans(s,0,t,1)));} //recursive method below, note s.charAt(0)==t.charAt(0).
}
private static int isTrans(String s, int i, String t, int j)
{
    if(i < s.length() && j < t.length()) //only as long as the indexes are within right bound
    {
        if(s.charAt(i) == t.charAt(j)) //character at 'transformed' string is the character at original string
        {
            if((j+1)<t.length()) //only as long as there are more characters
            {
                j++;
                isTrans(s,i,t,j); //check next character at transformed string
            }
        }
        else if((i+1)<s.length()) //ensures there is a next character at string s
        {
            if(s.charAt(i+1) == t.charAt(j)) //character is the next chracter at original string
            {
                i++;
                if((j+1)<t.length()) //only as long as there are more characters
                {
                    j++;
                    isTrans(s,i,t,j); //checks next characters at strings
                }
            }
            else{i=-1;} //not transformation
        }
        else{i=-1;} //not transformation
    }    
    return (i+1);
}

Программа не работает должным образом. Теперь вот любопытная вещь: запускать ее через отладчик, она делает все, как предполагалось, однако, когда она достигает команды " return (i+1) ", вместо того, чтобы фактически возвращать ее, она начинает выполнять рекурсивные вызовы для некоторых разум, тем временем уменьшая значение i до тех пор, пока оно не достигнет 0, и только затем вернет его, вызывая ложные негативы. Более конкретно, он поднимается вверх по стеку и "выполняет" рекурсивные вызовы isTrans(s,i,t,j).

Я хотел бы знать, почему это так, даже больше, чем способ решить такую проблему. Он даже не входит через iff, но сразу же вводит рекурсивные вызовы, уменьшая значение i до 0 и только затем возвращая его.

Цените любые комментарии!

Изменить: уточнить, что именно он делает, в соответствии с отладчиком. Если я попытаюсь понять, является ли "aabba" преобразование "aba" (оно находится под определениями выше), программа достигает желаемого значения для i 2. Тем не менее, он затем return (i+1) команду return (i+1) и внезапно возвращается к строке 17 в данном коде, затем следующий рекурсивный вызов в коде и обратно к нему - все это время уменьшает значение i до 0, Только тогда он выполняет команду вне функции.

Редактирование 2: После небольшого изменения настроек и воспроизведения кода, кажется, что без подключения к оператору return в конце функция "перескакивает" назад, пропуская "if", на рекурсивные вызовы, не выполняет их, но уменьшает i до 0 и только затем продолжается. Это связано с тем, что я вызываю isTrans (s, 0, t, 1)?

  • 2
    Вы уверены, что он идет вниз по стеку, а не вверх ? Другими словами, вы уверены, что функция, в которой вы работали, не была рекурсивным вызовом, и оператор return вернул вас назад?
  • 1
    Я не знаю, что такое преобразование строк. Можете ли вы дать некоторые объяснения некоторых строк, которые являются / не являются преобразованиями друг друга (и почему)? Также вы сравниваете строки, используя == , вы определенно хотите изменить это на .equals() , см. Stackoverflow.com/questions/513832/…
Показать ещё 9 комментариев
Теги:
string
recursion

1 ответ

1
Лучший ответ

Условием выхода является return i+1. Это никогда не сработает, даже если ваша логика сделала, потому что результат, который вы возвращаете, всегда больше, чем длина строки.

Вот что может произойти в вашем коде:

  1. Сначала, если условие выполнено
  2. j является инкретированным.
  3. Рекурсивный вызов.
  4. Больше нет, если условия выполнены, потому что я и j больше не указывают на одну и ту же букву.
  5. Он возвращает я + 1

Чтобы сделать это рекурсивно, вы, вероятно, сделали бы что-то вроде этого:

public class Main {
    public static void main(String args[])
    {
        String s = "aba";
        String t = "abz";
        System.out.println(isTrans(0, 0, s, t));
    }

    public static boolean isTrans(int si, int ti,String s ,String t)
    {
        // we have run out of source characters, or the source character has passed the transformation character. This is not a transformation.
        if (si > ti || si == s.length())
        {
            return false;
        }

        // we are at the end of the transformation string. This might be a transformation.
        if(ti == t.length())
        {
            return si == s.length()-1; // If we're at the end of our source string, otherwise it isn't.
        }

        // if the current positions contain identical characters...
        if (checkChar(si, ti, s, t))
        {
            // advance the transformation index.
            ti++; 
        }
        else
        {
            // otherwise, advance the source index.
            si++;
        }

        // recursion.
        return isTrans(si, ti, s, t);
    }

    private static boolean checkChar(int si, int ti, String s, String t)
    {
        return  (s.charAt(si) == t.charAt(ti));
    }

}

Надеюсь, вы сочли это полезным.

  • 0
    Извините за то, что не ясно, что за трансформация для меня, обновил исходный вопрос с ним. «аба» - это трансформация «аба» по моему определению, а также «ааба», «аабббббба» и так далее. Условием выхода является return i+1 , а не минус 1.
  • 0
    @Studentmath Я изменил свой ответ, чтобы лучше отразить ваш обновленный вопрос. Я надеюсь, что это помогает.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню