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
用简洁来避免创建更多的variables)
另外,您可以将此操作的更一般版本作为String
的扩展函数来编写:
fun String.rotate(n: Int) = drop(n % length) + take(n % length)
用法:
val str = "abcde" val r1 = str.rotate(1)
由于字符串是不可变的,所以必须将源字符串复制到数组中,对数组进行更改,然后从修改后的数组中创建一个新字符串。 调查:
- getChars()将字符串字符复制到数组中。
- 在该数组上执行算法,根据需要进行更改。
- 将修改的数组转换回带有String的字符串(char []) 。
更简单的解决方案:只要使用toMutableList()创建一个Char的MutableList,然后用joinToString一起加入。
例:
给定一个字符串输入,我们想交换位置posA和posB的字符:
val chars = input.toMutableList() val temp = chars[posA] chars[posA] = chars[posB] chars[posB] = temp return chars.joinToString(separator = "")