Scala实现pool函数触发StringIndexOutOfBoundsException问题求助
解决StringIndexOutOfBoundsException的问题
我来帮你搞定这个错误!首先得搞清楚你代码里的问题出在哪:
你写的filterNot(x => secret.apply(x) == word.apply(x))里,x是secret中的字符(比如'c'、'h'这些),而不是索引位置。当你调用apply(x)的时候,Scala会把Char类型自动转换成它的ASCII码值当作索引用——比如'h'的ASCII是104,而你的测试字符串"chess"只有5个字符,索引最大才4,这肯定就超出范围报错了!
正确的实现方式
我们需要同时遍历两个字符串的同索引字符,比较它们是否相等,只保留不相等的secret字符。用Scala的zip方法就能轻松实现这个需求:
def pool(secret: String, word: String): List[Char] = { secret.zip(word) .filterNot { case (sChar, wChar) => sChar == wChar } .map { case (sChar, _) => sChar } .toList }
代码解释
secret.zip(word):把两个字符串按索引一一配对,比如"chess".zip("caves")会得到List(('c','c'), ('h','a'), ('e','v'), ('s','e'), ('s','s'))filterNot:过滤掉配对后两个字符相等的元素,上面的例子里会去掉('c','c')和('s','s'),剩下List(('h','a'), ('e','v'), ('s','e'))map:提取每个配对里来自secret的字符,得到List('h','e','s')toList:转换成Char列表,满足返回值要求
测试验证
用你的测试用例跑一下:
pool("chess", "caves")→List(h, e, s),完全符合预期pool("chess", "swiss")→List(c, h, e),也没问题
额外补充(处理字符串长度不一致的情况)
如果你的场景里两个字符串可能长度不同,zip只会处理到较短字符串的长度。要是想保留secret里超出部分的字符,可以用zipAll来填充:
def pool(secret: String, word: String): List[Char] = { secret.zipAll(word, '\0', '\0') // 用空字符填充较短的一方 .filterNot { case (sChar, wChar) => sChar == wChar } .map { case (sChar, _) => sChar } .filter(_ != '\0') // 去掉填充的空字符 .toList }
内容的提问来源于stack exchange,提问作者Jae
相关产品推荐
相关产品推荐

