2016-03-28 63 views
6

我想將字符串從「abcde」交換到「bcdea」。所以我寫下我的代碼如下KotlinKotlin:如何在字符串中交換字符

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] 

它出錯了,如上述註釋行。我做錯了什麼?我怎麼能解決這個問題,並得到我想要的?

回答

6

Strings in Kotlin就像在Java中是不可變的,所以沒有string.set(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() 

然而,一個更簡單的實現你的目標(「BCDEA」從「ABCDE」)的方式就是「移動」一個字:

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

或使用Sequence方法:

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

感謝您的很好的解釋! – Elye

+0

考慮使用'buildString'作爲構建'String'的更簡潔的方法:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/build-string.html – hotkey

0

小號ince字符串是不可變的,您必須將源字符串複製到數組中,對數組進行更改,然後從修改後的數組中創建一個新字符串。看看:

  • getChars()將字符串字符複製到數組中。
  • 在該數組上執行算法,根據需要對其進行更改。
  • 將修改後的數組轉換回字符串String(char[])
4

您可以使用drop(1)first()(或take(1))做在同一行:

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

至於你的代碼,科特林String是不可改變的,你不能修改它的字符。爲了達到你想要什麼,你可以轉換StringCharArray,進行修改,然後做出一個新的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用於簡潔,以避免造成更多的變量)


此外,你可以這樣寫操作的更一般爲extension functionString

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

用法:

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

我想知道什麼是性能對於那些。在一個天真的實現中,帶有'CharArray'的版本必須是最高效的和局部的。另一方面,JIT可以優化其他的,所以有1個分配而不是3個。 – voddan

+1

@voddan,這裏是一個測試結果:https://gist.github.com/h0tk3y/bc508a573abfe8e8b3b3。看起來很奇怪,但是drop + take顯示它本身更好一點。 – hotkey

+0

哈,沒有人期望'StringBuilder'照耀在這裏:)謝謝你的測試! – voddan

0

簡單的解決辦法:只要使用toMutableList()來創建字符的MutableList,然後用joinToString加入它一起。

例子:

給定一個字符串輸入,我們要在交換位置POSA和儲蓄銀行的字符:

val chars = input.toMutableList() 
val temp = chars[posA] 
chars[posA] = chars[posB] 
chars[posB] = temp 
return chars.joinToString(separator = "")