Kotlin-字符串中的唯一字符
我的函数应该返回一个布尔值,指示输入字符串是否包含所有唯一字符 e、 g。 “abc”返回true,“abca”返回falseKotlin-字符串中的唯一字符,kotlin,functional-programming,unique,Kotlin,Functional Programming,Unique,我的函数应该返回一个布尔值,指示输入字符串是否包含所有唯一字符 e、 g。 “abc”返回true,“abca”返回false fun uniqueCharacters(s: String): Boolean = s.groupBy { it } .values .stream() .allMatch { it.size == 1 } 有没有更有效的方法来解决这个问题?如果我是以非函数方式解决这个问题,我会将所有字符存储在一个映射中,其值是到目前为止该字符的计数,如果它
fun uniqueCharacters(s: String): Boolean = s.groupBy { it }
.values
.stream()
.allMatch { it.size == 1 }
有没有更有效的方法来解决这个问题?如果我是以非函数方式解决这个问题,我会将所有字符存储在一个映射中,其值是到目前为止该字符的计数,如果它大于1,则中断并返回false
不确定如何最好地将其转换为函数式Kotlin代码。您可以使用函数和Set::add
作为它的谓词
fun main() {
println("abc".allUnique()) // true
println("abca".allUnique()) // false
}
fun String.allUnique(): Boolean = all(hashSetOf<Char>()::add)
fun main(){
println(“abc.allUnique())//true
println(“abca.allUnique())//false
}
fun String.allUnique():Boolean=all(hashSetOf()::add)
它是惰性的,函数在找到第一个重复项时返回结果您可以使用函数和Set::add
作为它的谓词
fun main() {
println("abc".allUnique()) // true
println("abca".allUnique()) // false
}
fun String.allUnique(): Boolean = all(hashSetOf<Char>()::add)
fun main(){
println(“abc.allUnique())//true
println(“abca.allUnique())//false
}
fun String.allUnique():Boolean=all(hashSetOf()::add)
它是惰性的,函数在找到第一个重复字符时返回结果可能最简单的方法是创建字符集,并检查其大小:
fun String.isUniqueCharacters() = toSet().size == length
(由于此函数仅取决于字符串的内容,因此将其作为扩展函数似乎是合乎逻辑的;这也使得调用更容易。)
至于性能,它有效地创建了一个字符的哈希表,然后检查条目数,即唯一字符的数量。所以这不是小事。但我想不出有什么方法比这更好
其他办法可能包括:
- 将字符复制到数组中,对其进行排序,然后对其进行扫描并比较相邻元素。这将节省一些内存分配,但需要更多的处理
- 如上所述,但使用手动编码的排序算法,可以发现重复项并提前返回。在有重复项的情况下,这将减少处理,但要付出更多编码的代价(并且在没有重复项的情况下,手工编码排序可能比库排序慢)
- 创建一个包含65536个布尔值(每个可能的
value*)的数组,所有布尔值都初始化为false,然后扫描字符串中的每个字符,检查相应的数组值(如果已设置,则返回false,否则设置)。这可能是最快的方法,但需要大量内存(初始化阵列的成本可能非常高。)Char
(*在Unicode中,当然还有更多的字符,但是Kotlin在内部使用UTF-16,所以我们只需要65536。)也许最简单的方法是创建一个字符集,并检查其大小:
fun String.isUniqueCharacters() = toSet().size == length
(由于此函数仅取决于字符串的内容,因此将其作为扩展函数似乎是合乎逻辑的;这也使得调用更容易。)
至于性能,它有效地创建了一个字符的哈希表,然后检查条目数,即唯一字符的数量。所以这不是小事。但我想不出有什么方法比这更好
其他办法可能包括:
- 将字符复制到数组中,对其进行排序,然后对其进行扫描并比较相邻元素。这将节省一些内存分配,但需要更多的处理
- 如上所述,但使用手动编码的排序算法,可以发现重复项并提前返回。这将在有重复项的情况下减少处理,但代价是编码要多得多。(并且,在没有重复项的情况下,手动编码的排序可能比库排序慢。)
- 创建一个包含65536个布尔值(每个可能的
value*)的数组,所有布尔值都初始化为false,然后扫描字符串中的每个字符,检查相应的数组值(如果已设置,则返回false,否则设置)。这可能是最快的方法,但需要大量内存(初始化阵列的成本可能非常高。)Char
fun String.uniqueCharacters(): Boolean = this.toCharArray().distinct().isNotEmpty()
另一种方法
fun String.uniqueCharacters(): Boolean = this.toCharArray().distinct().isNotEmpty()
很好!我以前从未见过这种一次完成方法引用的临时集合的实例化模式。我能问问你如何将其作为非扩展函数编写吗?@H1H1H1
fun allUnique(s:String):Boolean=s.all(hashSetOf()::add)
这确实是一个不错的解决方案+1Nice!我以前从未见过这种模式一次性实例化一个临时集合作为其方法引用。我能问一下您如何将其作为非扩展函数编写吗?@H1H1H1H1H1fun allUnique(s:String):Boolean=s.all(hashSetOf()::add)
这确实是一个不错的解决方案+1