过滤字符串,删除与同一索引中另一个字符串具有相同元素的所有元素



正如标题所说,我想实现一个函数,池,在删除给定字符串的所有元素后返回字符列表,这些元素与另一个字符串在相同的索引中具有相同的字母。由于我为获取给定索引中的元素而编写的代码,它给了我一个stringindexoutofboundexcepeption。我怎么解决这个问题?

我实现
def pool(secret: String, word: String) : List[Char] = { 
secret.filterNot(x => secret.apply(x) == word.apply(x)).toList
}

测试用例

pool("chess", "caves") => List(h, e, s)
pool("chess", "swiss") => List(c, h, e)

错误消息

java.lang.StringIndexOutOfBoundsException: String index out of range: 99
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:1515)
at scala.collection.StringOps$.apply$extension(StringOps.scala:188)
at $anonfun$pool$1(<console>:3)
at $anonfun$pool$1$adapted(<console>:3)
at scala.collection.StringOps$.filterNot$extension(StringOps.scala:1264)
at pool(<console>:3)
... 32 elided

x字符String.apply接受索引c具有aci代码99,因此当您执行"caves".apply('c')时,它会尝试访问"洞穴"中的字符;在索引99处,抛出,因为字符串不够长

如果你坚持使用实际的索引,像这样的东西可能会工作:

secret.zipWithIndex.collect { case (c, i) if word(i) != c => c }.mkString

但是如果word碰巧比secret短,这仍然会抛出。如果您愿意,可以添加另一个条件(case (c,i) if i >= word.length || word(i) != c => c))来防止这种情况,但是这样的东西会更容易读,更习惯(在scala中通常不赞成直接索引访问,因为它经常会导致微妙的性能问题,并导致读者花费额外的周期来证明它在给定情况下是合法的):

secret
.iterator
.zipAll(word, 0.toChar, 0.toChar)
.collect { case (a,b) if a != b && a != 0.toChar => a }
.mkString

最新更新