Java 递归长字程序设计

Java 递归长字程序设计,java,recursion,longest-substring,Java,Recursion,Longest Substring,我终于如愿以偿了。谢谢大家的帮助,我想强调这不是家庭作业 public static void main(String[] args) { String input = "Java is a programming language"; StringTokenizer st = new StringTokenizer(input); System.out.print(longestWord(input)); } public static String

我终于如愿以偿了。谢谢大家的帮助,我想强调这不是家庭作业

public static void main(String[] args) {
    String input = "Java is a programming language";
            StringTokenizer st = new StringTokenizer(input);
    System.out.print(longestWord(input));

}

public static String longestWord(StringTokenizer st) {
    if (!st.hasMoreTokens()) {
        return "";

    } else {
        String token = st.nextToken(); 
        String longestInTheRest = longestWord(st);
        if (token.length() > longestInTheRest.length()) { 

            return token;

        } else {
            return longestInTheRest;
        }

为了使递归工作,您需要传递一个当前状态,即要比较的当前最长字


如果答案看起来像是家庭作业,那么我不包括答案。如果答案不是,请告诉我。

以下内容不太正确:

else if (token.length() > result.length()) {
执行上述语句时,
结果始终是

函数应该返回以下较大值:(1)令牌的长度
;(2) 递归调用返回的单词的长度

您还可能会考虑这两个
s.substring()
调用是否完全符合您的要求,或者是否存在问题。打印出
token
rest
(或在调试器中检查它们)可能很有用

既然这看起来像家庭作业,我就到此为止

    result = token;
    return longestWord(rest);

这是错误的部分。result保存令牌,但随后退出该方法,再次输入并将result设置为“”。向方法签名添加另一个参数字符串currentLongest,这样它就不会丢失。

您正在将当前单词与结果进行比较,但结果是一个局部变量,它总是设置为
“”
(顺便说一句,它不是空字符串,而是一个包含空格的字符串)

您应该将当前结果作为参数传递给方法,并以空字符串作为结果开始


你也有一个bug,因为你不修剪你的令牌,因此把前面的空白当作单词的一部分。

你需要测试是否有一个空格。

差不多

int index = s.indexOf(' ');
if (index < 0) return s;
int index=s.indexOf(“”);
如果(指数<0)返回s;

我会采取稍微不同的方法来解决这个问题:

首先,我将把字符串转换成一个数组,它更适合递归方法

public static String longestWord(String string) {
    return longestWord(string.split(" "), "");
}
然后我们可以考虑递归方法。如果我们递归地传入一个较小的数组,我们知道最终会传入一个空数组-这是我们的基本情况,我们已经枚举了所有元素,所以只需返回作为参数传入的最长的元素。在递归情况下,我们检查(现在更小)数组的第一个元素是否比当前最长的元素长,并递归地传入两个元素中较长的元素

private static String longestWord(String[] strings, String currentLongest) {
    if (strings == null || strings.length == 0) {
        return currentLongest;
    }
    String[] newStrings = Arrays.copyOfRange(strings, 1, strings.length);
    String longest = strings[0].length() < currentLongest.length() ? currentLongest : strings[0];
    return longestWord(newStrings, longest);
}
私有静态字符串longestWord(字符串[]字符串,字符串currentLongest){
if(strings==null | | strings.length==0){
返回电流最长;
}
String[]newStrings=Arrays.copyOfRange(strings,1,strings.length);
字符串最长=字符串[0]。长度();
返回最长的单词(新闻字符串,最长);
}

注意:这也可以通过在数组中使用索引而不是复制来实现。然而,在实践中,这是一种过于优化的方法-它使其更难阅读,并且不可能对任何人都有利。

另一种解决方案,以更为实用的方式编写-请注意,我没有在递归方法的每次调用中分配新字符串(只有开始时的
split
操作分配新字符串)。我还采纳了Robert的建议,首先将原始问题转换为数组上的递归,这使事情变得更简单:

public static String longestWord(String s) {
    return longestWord(s.split("\\s+"), 0, 0);
}

public static String longestWord(String[] words, int currentIdx, int longestIdx) {
    if (currentIdx == words.length)
        return words[longestIdx];
    return longestWord(words, currentIdx + 1,
        words[currentIdx].length() > words[longestIdx].length() ? currentIdx : longestIdx);
}
上述解决方案的诀窍在于,我的递归超越了字符串数组的索引,而不是字符串本身。这就是我避免在每次调用时创建新字符串的原因。不需要
子字符串
copyOfRange
数组复制
新字符串()
或类似操作,从而产生更优雅的解决方案

编辑:

我稍微简化了上面的代码,使其更容易理解。关于
split
方法,这是一个标准的字符串操作,请看下面的示例


为什么使用递归?不管怎样,你的问题在于你不分享结果。token.length()>result.length()几乎总是解析为true,因为此时result.length始终是一个带1个空格(初始值)的字符串。具体结果作为你的方法中的一个参数,你很好,我没有递归就做到了,我正在尝试递归来准备我的考试,我理解我的错误,谢谢你;然而,我无法修复itRecursion,增加了计算开销,但它仍然在许多地方使用,因为它直观,因此易于编程,而且当研究的问题计算强度较低时。在这种情况下,递归只会使它变得更复杂,所以进行迭代吧。这不是一个家庭作业,我只是在为考试做准备,你们的答案信息量很大。我明白了,但我还是少了一些东西,谢谢你。谢谢你,我做了我的修剪部分。这不是家庭作业,我只是在为期末考试而努力。谢谢你的关心,谢谢你的关心。这是家庭作业,没有完整的解决方案-1对于您来说,这很好,但我不知道如何使用split,也不理解最后一个return语句。你能用另一种方法代替分裂吗?奥普说他在准备考试。知道几种不同的方法来解决一个问题是很好的。好的,但你们能给我解释一下最后一个返回语句吗?我想若我能理解最后一个返回语句,这对我的工作会很有用exam@JohnMyung我更新了我的答案,使它更容易理解。正如我所说,
split
是标准的,也是最简单的分割字符串的方法。是的,他确实说过发布答案很好,所以取消了-1。很抱歉
public static String longestWord(String s) {        
    return longestWord(s.split(" "), 0, 0);
}

public static String longestWord(String[] words, int currentIdx, int longestIdx) {
    if (currentIdx == words.length)
        return words[longestIdx];
    int idx;  // temporarily stores the index of the current longest word
    if (words[currentIdx].length() > words[longestIdx].length())
        idx = currentIdx;
    else
        idx = longestIdx;
    return longestWord(words, currentIdx + 1, idx);
}