Kotlin:如何在字符串中交换字符

我想换一个字符串从“abcde”到“bcdea”。 所以我在Kotlin写下了我的代码

var prevResult = "abcde" var tmp = prevResult[0] for (i in 0..prevResult.length - 2) { prevResult[i] = prevResult[i+1] // Error on preveResult[i] } prevResult[prevResult.length-1] = tmp // Error on preveResult[prevResult.lengt-1] 

它如上所述注释行出错。 我做错了什么? 我怎么能解决这个问题,得到我想要的?

Kotlin中的字符串就像Java一样是不可变的,所以没有string.set(index, value) (这是string[index] = value等价的string[index] = value )。

要创建一个字符串,你可以使用一个StringBuilder ,构造一个CharSequence并使用joinToString ,在一个普通数组( char[] )上操作或者执行result = result + nextCharacter (每次创建一个新的字符串 – 这是最昂贵的办法)。

以下是你如何使用StringBuilder来做到这一点:

 var prevResult = "abcde" var tmp = prevResult[0] var builder = StringBuilder() for (i in 0..prevResult.length - 2) { builder.append(prevResult[i+1]) } builder.append(tmp) // Don't really need tmp, use prevResult[0] instead. var result = builder.toString() 

然而,实现你的目标(“abcde”中的“bcdea”)的一种简单的方法就是“移动”一个字符:

 var result = prevResult.substring(1) + prevResult[0] 

或使用Sequence方法:

 var result = prevResult.drop(1) + prevResult.take(1) 

您可以使用drop(1)first() (或take(1) )在一行中完成:

 val str = "abcde" val r1 = str.drop(1) + str.first() val r2 = str.drop(1) + str.take(1) 

至于你的代码,Kotlin String是不可变的,你不能修改它的字符。 为了实现你想要的,你可以将一个String转换为CharArray ,修改它,然后创建一个新的String

 val r1 = str.toCharArray().let { for (i in 0..it.lastIndex - 1) it[i] = it[i+1] it[it.lastIndex] = str[0] // str is unchanged String(it) } 

let用简洁来避免创建更多的变量)


另外,您可以将此操作的更一般版本作为String的扩展函数来编写:

 fun String.rotate(n: Int) = drop(n % length) + take(n % length) 

用法:

 val str = "abcde" val r1 = str.rotate(1) 

由于字符串是不可变的,所以必须将源字符串复制到数组中,对数组进行更改,然后从修改后的数组中创建一个新字符串。 调查:

  • getChars()将字符串字符复制到数组中。
  • 在该数组上执行算法,根据需要进行更改。
  • 将修改的数组转换回带有String的字符串(char []) 。