【问题标题】:Odd/curious behaviour in a recursive function递归函数中的奇怪/奇怪行为
【发布时间】:2014-06-06 17:24:42
【问题描述】:

我正在尝试编写一个函数来检查一个字符串是否是对前一个字符串的一组操作的结果。具体来说,字符串“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,然后才返回。

欣赏任何 cmets!

编辑:根据调试器说明它到底做了什么。如果我尝试查看"aabba" 是否是"aba" 的转换(它在上述定义下),则程序会达到i - 2 的所需值。然而,它然后到达命令return (i+1),并突然返回到给定代码中的第17行,然后代码中的下一个递归调用,并返回到它 - 同时将i的值减小回@987654337 @。只有这样它才会在函数之外执行命令。

编辑 2:在对代码进行一些调整和玩弄之后,似乎 没有连接到 return 语句,最后函数'跳转'向后,跳过'if's,到递归调用-不执行它们,但将i减少到0,然后才继续。和我调用 isTrans(s,0,t,1) 有关系吗?

【问题讨论】:

  • 您确定它会向下堆栈而不是向上吗?换句话说,你确定你所在的函数不是递归调用,而 return 语句把你带回来了吗?
  • 我不知道什么是字符串转换。您能否举例说明一些相互之间是/不是相互转换的字符串(以及为什么)?此外,您使用== 比较字符串,您非常想将其更改为.equals(),请参阅stackoverflow.com/questions/513832/…
  • 您在递归调用时没有使用isTrans() 的返回值,这会导致问题吗?第一次调用总是会返回 [-1, 1] 中的内容。
  • 字符串相等性未使用s == t 进行测试。
  • 如果您将这些调用注释掉,它的功能将完全相同,除了它们可能抛出的任何异常。如果您仔细观察,它们并没有改变任何东西

标签: java string recursion


【解决方案1】:

您的退出条件是return i+1。即使您的逻辑有效,这也永远不会起作用,因为您返回的结果总是比字符串的长度大一。

以下是您的代码中可能发生的情况:

  1. 先满足条件
  2. j 递增。
  3. 递归调用。
  4. 如果条件满足则不再,因为 i 和 j 不再指向同一个字母。
  5. 返回 i+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));
    }

}

希望对您有所帮助。

【讨论】:

  • 对不起,我不清楚转换对我来说是什么,用它更新了原始问题。 “aba”是我定义下的“aba”的变形,“aaba”、“aabbbbbba”等也是。退出条件是return i+1,不是负1。
  • @Studentmath 我已更改我的答案以更好地反映您更新的问题。我希望它有所帮助。
  • 我想我现在明白我做错了什么,我想我明白如何实施你的想法来解决我的问题。非常感谢,它确实澄清了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
  • 2016-11-07
  • 2013-07-23
  • 2018-11-13
  • 2015-01-31
  • 1970-01-01
  • 2019-04-11
相关资源
最近更新 更多