Kotlin - 两个指针 - 嵌套 While 循环导致:线程“main”中出现异常 java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:1

Kotlin - Two Pointer - Nested While loops causing: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1

提问人:GoGuy 提问时间:10/23/2023 最后编辑:GoGuy 更新时间:10/23/2023 访问量:36

问:

在下面的代码示例中,我试图通过删除 Leetcode 上的问题来解决字典中最长的单词。我认为这个解决方案应该有效,但由于某种原因,下面的嵌套 while 循环似乎破坏了该功能,我不知道为什么。

我收到的错误是“第 20 行:线程”main“java.lang.StringIndexOutOfBoundsException 中的异常:字符串索引超出范围:1。 话虽如此,当我进行多次检查以确保不会发生这种情况时,我根本不知道这个错误是如何发生的。此外,循环的包装器似乎被调用的次数似乎比字典中的索引数还要多。

我发现最接近找出可能出错的地方的方法是在包装器 For 循环的顶部放置一个 println(i),并在包装器 Do - While 循环中注释掉指示的 While 循环。

当这些内部循环被取消注释时,该函数似乎正在获取答案,但 for 循环打印 0,1,2,3,0,并且该函数返回错误“第 20 行:线程”main“中的异常 java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:1。 当我注释掉这些循环时,该函数会正确打印 0,1,2,3 并完成返回错误答案。

我不知道为什么这些循环会导致包装器 For 循环从 0 开始运行更多次并返回错误 1。这甚至是问题吗?

class Solution {
    fun findLongestWord(s: String, dictionary: List<String>): String {
        var answer = ""

        for (i in dictionary.indices) {
            
            // Printing i to test the iterations of function
            // Prints 0, 1, 2, 3 when below while loops are commented out
            // Prints 0,1,2,3,0 when the below two while loops aren't commented out.
            println(i)
            if (answer.length > dictionary[i].length) {
                
                continue
            }
            var tempString = s.toCharArray().toMutableList()
            
            var low = 0
            var dictLow = 0
            var high = tempString.lastIndex
            var dictHigh = dictionary[i].lastIndex
          
            do {
                // Commenting out the below two while loops causes function to work
                while (tempString.size >= answer.length && tempString.isNotEmpty() && tempString[low] != dictionary[i][dictLow] ) {
                    tempString.removeAt(low)
                    high -= 1

                }

                while (tempString.size >= answer.length && tempString.isNotEmpty() && tempString[high] != dictionary[i][dictHigh]) {
                    tempString.removeAt(high)
                    high -= 1
                }

                if (tempString.joinToString("") == dictionary[i]) {
                    var potentialAnswer = tempString.joinToString("")
                    if (potentialAnswer.length > answer.length) {
                        answer = potentialAnswer
                    } else if (potentialAnswer.length == answer.length) {
                        var list = mutableListOf(potentialAnswer, answer).sorted()
                        answer = list[0]
                    }
                    break
                }
                else {
                    low += 1
                    high -= 1
                    dictLow += 1
                    dictHigh -= 1
                }
                

            } while (tempString.size > answer.length && low < high) 
        }

        return answer
    }
}
Kotlin for 循环 指针 while-loop indexoutofboundsexception

评论


答:

0赞 AndrewL 10/23/2023 #1

我不明白你想实现什么,但这里有一些需要检查的东西:

while (tempString.size >= answer.length 
&& tempString.isNotEmpty() && tempString[low] != dictionary[i][dictLow] ) {

我认为唯一可以提高的部分是.你稍后开始并增加它,但你没有保护条件,所以不可避免地,我想,你会遇到一个字符少于 ...因此例外StringIndexOutOfBoundsExceptiondictionary[i][dictLow]dictLow=0dictLow

评论

0赞 GoGuy 10/23/2023
感谢您的回复 AndrewL。至于您强调的部分,在某些情况下这绝对可能是一个问题,但是该问题具有限制:1 <= dictionary[i].length <= 1000。因此,dictionary[i] 的索引始终为 0。我试图弄清楚的是为什么这些 While 循环会导致包装 For 循环再次遍历 0。我编辑了问题,以包括“i”打印的确切值。0,1,2,3,0 表示由于某种原因它再次循环。当我从内部删除两个 while 循环时,它会正确地循环 0,1,2,3。
0赞 AndrewL 10/23/2023
(我仍然不知道你想实现什么逻辑!,但是......这两个循环不是“对称的”,我的意思是循环 2 引用和递减,但循环 1 引用但不递减它递减。这是对的吗?*high*lowlowhigh
0赞 GoGuy 10/24/2023
对不起,让我描述一下逻辑!'s' 变量是一串字母。字典是一个字符串列表。我应该返回字典中最长的字符串,该字符串可以通过删除一些给定的字符串 ('s') 字符来形成。我遍历字典中的每个字符串,while 循环从“s”字符串的开头和结尾删除字母,直到它们在当前字符串中找到字母。在这两种情况下,我们都会降低高音,因为如果我们删除索引 0,每个字母都会降低一个索引,因此要在高中引用相同的字符,我们必须递减高......
0赞 GoGuy 10/24/2023
如果我们删除右侧(高)侧的字符,我们仍然需要递减高音以引用“s”字符串中的下一个最低字符。然后,我们检查该字符串是否与字典中的当前字符串匹配。如果是这样,如果它比当前答案长,我们可能会将其设置为答案。如果它与字典中的字符串不匹配,我们将“s”字符串的低和高递增,以继续删除可能与字典字符串中接下来的两个字母不匹配的下一个字母。这就是为什么 dictlow 和 dicthigh 也会递增和递减的原因。还不清楚吗?