[英]Creating a method that generates all permutations of string in kotlin using recursion
尝试编写一些代码来生成输入字符串的所有排列作为递归练习,但无法弄清楚为什么会出现堆栈溢出错误。
fun main() {
println(subSet(listOf("abcd")))
}
fun subSet(s: List<String>): List<String>{
return listOf<String>() + createSubSets(s)
}
fun createSubSets(s: List<String>): List<String>{
if(s.isEmpty()){
return listOf()
}
return s.mapIndexed{i, elem ->
elem + createSubSets(s.drop(i))
}
}
这个语句导致无限递归:
return s.mapIndexed { i, elem ->
elem + createSubSets(s.drop(i))
}
其中,第一次迭代的i
值为0
( elem
是索引0
处的字符),递归调用createSubSets(s.drop(i))
等效于createSubSets(s)
,因为从字符串返回原始字符串。
你的递归函数不安全。 它永远迭代,不断添加到堆栈中,这就是为什么您会遇到堆栈溢出。
除了修复你的算法,你可以做两件事来改善这种情况:
fun main() {
println(subSet(listOf("a", "b", "c", "d")))
}
fun subSet(s: List<String>): List<String>{
return createSubSets(s, 0)
}
fun createSubSets(s: List<String>, index: Int): List<String> {
if (index > s.lastIndex) {
return emptyList()
}
val otherElements = s.subList(0, index) + s.subList(index + 1, s.size)
val element = s[index]
return otherElements.map { element + it } + createSubSets(s, index + 1)
}
// [ab, ac, ad, ba, bc, bd, ca, cb, cd, da, db, dc]
fun main() {
println(subSet(listOf("a", "b", "c", "d")))
}
fun subSet(s: List<String>): List<String>{
return createSubSets(s, 0, emptyList())
}
tailrec fun createSubSets(s: List<String>, index: Int, carryOn: List<String>): List<String> {
if (index > s.lastIndex) {
return carryOn
}
val otherElements = s.subList(0, index) + s.subList(index + 1, s.size)
val element = s[index]
return createSubSets(s, index + 1, carryOn + otherElements.map { element + it })
}
// [ab, ac, ad, ba, bc, bd, ca, cb, cd, da, db, dc]
请注意,尾递归版本总是将自己称为最后一件事。 具体来说,它不会对调用自身的结果执行任何操作。 这就是它必须将结果传递到下一次调用的原因,但这也是它堆栈安全的原因。
最后,请注意您根本不需要递归来解决这个问题:
fun main() {
println(subSet(listOf("a", "b", "c", "d")))
}
fun subSet(s: List<String>): List<String>{
return createSubSets(s)
}
fun createSubSets(s: List<String>): List<String> {
return s.mapIndexed { i, element ->
val otherElements = s.subList(0, i) + s.subList(i + 1, s.size)
otherElements.map { element + it }
}.flatten()
}
// [ab, ac, ad, ba, bc, bd, ca, cb, cd, da, db, dc]
fun main() {
permutations("abcd","") }
fun permutations(str:String, storedString: String){
if(str.length == 1)
println(storedString+str)
else
for(i in str.indices)
permutations(str.removeRange(i,i+1),storedString+str[i])}
另一个例子:
fun String.permute(result: String = ""): List<String> =
if (isEmpty()) listOf(result) else flatMapIndexed { i, c -> removeRange(i, i + 1).permute(result + c) }
fun main() {
println("abc".permute()) // [abc, acb, bac, bca, cab, cba]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.