【问题标题】:Recursion method leads to stack overflow in Java program递归方法导致Java程序中的堆栈溢出
【发布时间】:2016-03-12 06:16:59
【问题描述】:

所以我的程序的前提是它是一个JavaFX GUI,会显示“分析”的结果。

我有 6 个不同的字符串,从长度 1 到长度 3

String[] phrases = new String[] { "ar", "ne", "um", "ll", "r", "ose" };

以及我只使用名称(字符串值)的对象数组列表。

到目前为止,我已经能够设置输入数据以显示 GUI 的循环。

private void analyzePlantMenu(ArrayList<Plant> plants)
{
    String[] phrases = new String[] { "ar", "ne", "um", "ll", "r", "ose" };
    BorderPane sects = new BorderPane();

    String current = "";
    TextArea analysis = new TextArea();

    for (Plant myplant : plants)
    {
        current = myplant.getName();
        for (int q = 0; q < phrases.length; q++)
        {
            String trial = phrases[q];
            analysis.appendText("The number of times " + phrases[q] + " appeared in the word " + current + " were "
                    + compareTrials(trial, current) + "\n");
        }
    }

我遇到的问题是为 compareTrials

返回正确的值

这是我到目前为止的递归方法

private int compareTrials(String trial, String current)
{
    int shift2 = 0 + trial.length();
    int shift = 0;
    if (shift == current.length())
    {
        return 0;
    }
    else if (current.substring((shift), (shift2)).contains(trial))
    {
        shift2 += 1;
        shift += 1;
        return 1 + compareTrials(trial, current);
    }
    else
    {
        shift2 += 1;
        shift += 1;
        return 0 + compareTrials(trial, current);
    }
}

有人可以帮我理解为什么在遍历单词时会出现堆栈溢出错误吗?

我最好的猜测是,要么是因为我的基本情况不是基本情况,要么我的 else 语句会无限期地继续下去

编辑

我改变我的方法来检测这些值而不是进入堆栈溢出的方法涉及将多个变量移出 compareTrials 方法并将它们传递进去。外观改动和编辑代码如下

private void analyzePlantMenu(ArrayList<Plant> plants)
{
    String[] phrases = new String[] { "ca", "in", "us", "ll", "r", "ose" };
    BorderPane sects = new BorderPane();

    String current = "";
    TextArea analysis = new TextArea();

    for (Plant myplant : plants)
    {
        current = myplant.getName();
        for (int q = 0; q < phrases.length; q++)
        {
            String trial = phrases[q];
                **int total = 0;
                int shift2 = trial.length();
                int shift = 0;**
            analysis.appendText((q+1) + ". The number of times " + phrases[q] + " appeared in the word " + current
                    + " were " + compareTrials(trial, current, shift, shift2, total) + "\n");
        }
        analysis.appendText("Finished analysis of " + current.toUpperCase() + "\n");
        analysis.appendText("\n");
    }

还有递归方法

private int compareTrials(String trial, String current, int shift, int shift2, int total)
{
    if (shift2 >= current.length() + 1)
    {
        System.out.println(shift + " " + shift2);
        return total += 0;
    }
    else if (current.substring((shift), (shift2)).equalsIgnoreCase((trial)))
    {
        System.out.println(shift + " " + shift2);
        return total += 1 + compareTrials(trial, current, shift + 1, shift2 + 1, total);
    }
    else
    {
        System.out.println(shift + " " + shift2);
        return total += 0 + compareTrials(trial, current, shift + 1, shift2 + 1, total);
    }
}

【问题讨论】:

  • 您的停止条件是 current 的长度为 0,这永远不会发生,因为它不会改变。我认为您需要将substring(在else if 语句中)的结果影响到current(或其他变量)。
  • 好的。 shift2shift 1 变量是我尝试从当前单词的左端开始到单词的右端的尝试。是否可以在递归中像这样递增?
  • 您可以将这些作为参数提供给compareTrials 方法:compareTrials(String trial, String current, int shift, int shift2)。但这似乎过于复杂。请参阅我的回复以了解总体思路。

标签: java recursion


【解决方案1】:

根据我对您的需求的了解,我会采用这样的递归方法:

private int compareTrials(String trial, String current, int startIndex) {
    int nextIndex = current.indexOf(trial, startIndex);
    if(nextIndex == -1) {
        return 0;
    }
    return 1 + compareTrials(trial, current, nextIndex + trial.length());
}

第一个电话是startIndex0

【讨论】:

    【解决方案2】:

    你的两个递归调用,

        return 1 + compareTrials(trial, current);
    

        return 0 + compareTrials(trial, current);
    

    具有参数与传入参数完全相同trialcurrent 永远不会改变。 因此,您不能指望它会收敛,因此它只会以相同的参数无限次调用compareTrials()

    【讨论】:

      【解决方案3】:

      我相信您的问题源于这样一个事实,即每当您递归调用 compareTrials() 时。基本上,您在每个返回方法中所做的只是使用 same 方法参数再次调用递归方法。所以这只是一个无限的“循环”。

      我首先重新定义trialcurrent,然后使用修改后的参数调用compareTrials() 方法。

      【讨论】:

        猜你喜欢
        • 2012-07-24
        • 2020-12-17
        • 2010-10-26
        • 2020-07-13
        • 2011-02-26
        • 1970-01-01
        相关资源
        最近更新 更多