Kotlin中统计指定字符数组在字符串中的出现次数及方案咨询
解答:统计string1字符在string2中的出现次数
嘿,我来帮你搞定这个问题!首先咱们先解决正则的困扰,然后再聊聊Kotlin里更简单高效的实现方式~
一、正则表达式的正确写法
你的需求是匹配string1里的任意字符,所以正则可以用**字符类(Character Class)**来实现:
val pattern = Regex("[${string1}]")
这个正则的意思是:匹配string1中包含的任意单个字符。不过要注意,如果string1里有正则特殊字符(比如^、]、-这类),直接写会导致正则失效,这时候可以用Regex.escape来转义每个字符:
val escapedChars = string1.map { Regex.escape(it.toString()) }.joinToString("") val pattern = Regex("[${escapedChars}]")
这里要提醒你:如果直接用pattern.findAll(string2).count(),得到的是所有匹配字符的总次数(比如你的例子里总次数是1+1+3+2=7),但你要的是每个字符单独的出现次数,所以得对匹配结果做分组统计:
val charCountMap = pattern.findAll(string2) .groupBy { it.value } .mapValues { it.value.size } println(charCountMap) // 你的例子会输出 {H=1, e=1, l=3, o=2}
二、Kotlin里更优的实现方式
其实完全没必要用正则,Kotlin的集合操作就能更直观、高效地完成这个需求(正则有额外的编译和匹配开销),给你两种推荐写法:
方式1:先预存string2的字符频率,再快速查询
val string1 = "Hello" val string2 = "Hello world" // 先遍历一次string2,生成每个字符的频率Map,避免重复遍历 val string2CharFreq = string2.groupingBy { it }.eachCount() // 对string1的字符去重后,查询每个字符的频率(默认0如果不存在) val result = string1.toSet().associateWith { string2CharFreq.getOrDefault(it, 0) } println(result) // 输出 {H=1, e=1, l=3, o=2}
这种方式在string2很长的时候优势明显,因为只需要遍历string2一次,后续查询都是O(1)的时间。
方式2:过滤+分组统计,代码更简洁
val string1 = "Hello" val string2 = "Hello world" val result = string2.filter { it in string1 } .groupingBy { it } .eachCount() println(result) // 同样得到 {H=1, e=1, l=3, o=2}
这种写法更简洁,先把string2里属于string1的字符过滤出来,再分组统计每个字符的次数,可读性拉满~
总结
- 如果一定要用正则,字符类
[${string1}](记得转义特殊字符)可以满足匹配需求,但要注意区分总次数和单个字符的次数; - 更推荐用Kotlin的集合操作,代码更简洁、高效,也更容易维护,上面两种方式都比正则更适合这个场景。
内容的提问来源于stack exchange,提问作者Anuj TBE
相关产品推荐
相关产品推荐

