0

我是 Kotlin 的新手,对编程也很陌生,所以请保持温和 :)

假设我有一个字符串(它被优化为没有任何重复的字符),我想将该字符串中的所有字符与字母表进行比较,该字母表被声明为一个可变的字符列表。我想删除字符串中出现的字母表中的任何字符。我的代码如下

var alphabet=mutableListOf('a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z') 
    var key="keyword"
    println(key)    
    for (i in key.indices)
        {for (j in alphabet.indices)
             {if (key[i] == alphabet[j])
                  alphabet.removeAt(j)     // 1. this line have error
                  //print(alphabet[j])  //2. but this line runs fine
}}}

在上面的代码中,“alphabet.removeAt(j)”命令出现错误,所以我尝试另一个命令打印出字符而不是删除它们,它运行良好。我阅读了一些文章,我知道这个错误与无效索引有关,但我使用了“indices”键,我认为它非常安全。请帮忙

4

3 回答 3

2

使用 迭代是安全的alphabet.indices,但在修改集合时迭代集合是不安全的。请注意,indices返回完整字母表的索引,但随后您从中删除了一些项目,使其更短,因此索引不再有效。

您无需遍历集合即可找到要删除的项目。你可以这样做:

alphabet.remove(key[i])

但老实说,你不需要做任何事情。您的问题实际上是两组相减,您可以更轻松地解决它:

('a'..'z').toSet() - "keyword".toSet()
于 2021-07-28T10:23:35.557 回答
1

但我使用了“indices”键,我认为它很安全

好吧,indices集合仅在进入循环时评估一次,而不是在每次迭代开始时。即使你改变了内部循环的大小,alphabet内部循环仍然会循环相同的次数,因为它不会alphabet.indices再次评估。它只会在外循环的下一次迭代中再次这样做,但您的代码会在此之前抛出异常。

除了j在删除项目时减少之外,您还可以通过以下方式解决此问题

key.forEach(alphabet::remove)
于 2021-07-28T10:24:54.053 回答
1

您可以将整个循环简化为:

alphabet.retainAll{ it !in key })

或者

alphabet.retainAll { !key.contains(it) }

或者,如果您希望过滤后的列表成为新列表而不是就地执行:

val filtered = alphabet.filter { it !in key }
于 2021-07-28T10:18:09.787 回答