如何根据模式替换任意位置的任意字符
How to replace any character in any position according to the pattern
我遇到如下问题:
给定一个字符串和一个需要替换的字符和位置,例如:
输入:
字符串:str = ABCDEFGH,前缀 = "_" 和位置 = 3,
输出:
结果 = AB_CDE_FGH
输入:
字符串:str = 10000000,前缀 = "_" 和位置 = 3,
输出:
结果 = 10_000_000
输入:
字符串:str = 10000000,前缀 = "_" 和位置 = 2,
输出:
结果 = 10_00_00_00
这是我的代码:
fun convertNumberByCharacter(pattern:String,position: Int,characters: String):String{
val strBuilder = StringBuilder()
val arr = pattern.toCharArray()
return if (arr.size>position){
for (i in 0..arr.size-1){
if (i%position==0){
strBuilder.append(characters)
}
strBuilder.append(arr[i])
}
strBuilder.toString()
}else{
pattern
}
}
注意:本题不能使用DecimalFormat和NumberFormat
拜托,任何人都可以帮助我。谢谢。
试试这个
val str = "ABCD"
val prefix = "_"
val position = 3
val result = StringBuilder()
val offset = position - str.length % position
for (i in str.indices) {
if (i != 0 && (i + offset) % position == 0) {
result.append(prefix)
}
result.append(str[i])
}
println(result)
我觉得reverse
字符串然后循环,在某个位置加前缀然后reverse
再次解决这个问题
我认为完成此操作的最简洁方法是使用 chunked() and joinToString() 的组合。不幸的是,stdlib 只提供了 chunked()
从左边开始计数,我们这里需要从右边开始计数。不过,我认为实施 chunkedRight()
并将其与 joinToString()
一起使用会更干净。
fun CharSequence.chunkedRight(size: Int): List<String> {
if (isEmpty()) return emptyList()
val fullChunks = length / size
val firstSize = length - fullChunks * size
// capacity may be too big by one - no problem here
return ArrayList<String>(fullChunks + 1).apply {
if (firstSize > 0) {
add(substring(0, firstSize))
}
(firstSize until length step size).forEach {
add(substring(it, it + size))
}
}
}
或者:
fun CharSequence.chunkedRightSequence(size: Int): Sequence<String> {
if (isEmpty()) return emptySequence()
val firstSize = (length - 1) % size + 1
return sequenceOf(substring(0, firstSize)) +
(firstSize until length step size).asSequence()
.map { substring(it, it + size) }
}
然后我们可以这样使用它:
println("ABCDEFGH".chunkedRight(3).joinToString("_"))
println("10000000".chunkedRight(3).joinToString("_"))
println("10000000".chunkedRight(2).joinToString("_"))
或者我们可以为此创建一个专门的函数。
这是一个使用标准 Kotlin 库函数的实现 - 无需处理索引。
fun main() {
println(convert("ABCDEFGH", 3, "_")) // AB_CDE_FGH
println(convert("10000000", 3, "_")) // 10_000_000
println(convert("10000000", 2, "_")) // 10_00_00_00
}
fun convert(input: String, position: Int, separator: String) =
input
// reverse the string
// e.g. HGFEDCBA
.reversed()
// split into chunks
// e.g. [HGF], [EDC], [BA]
.chunked(position)
// join the chunks back into a string, with a separator
// e.g. HGF_EDC_BA
.joinToString(separator)
// un-reverse the string - done!
// e.g. AB_CDE_FGH
.reversed()
从字符串末尾开始计数很重要(您当前的循环从左侧开始)。要进入 'backwards',我已经 reversed the input string. As String is an Iterable I've used chunk to split it into position
sizes, and then 'inserted' the separator using joinToString 在分块列表中。最后,我再次调用 reverse
以撤消初始反转。
我遇到如下问题:
给定一个字符串和一个需要替换的字符和位置,例如:
输入: 字符串:str = ABCDEFGH,前缀 = "_" 和位置 = 3, 输出: 结果 = AB_CDE_FGH
输入: 字符串:str = 10000000,前缀 = "_" 和位置 = 3, 输出: 结果 = 10_000_000
输入: 字符串:str = 10000000,前缀 = "_" 和位置 = 2, 输出: 结果 = 10_00_00_00
这是我的代码:
fun convertNumberByCharacter(pattern:String,position: Int,characters: String):String{
val strBuilder = StringBuilder()
val arr = pattern.toCharArray()
return if (arr.size>position){
for (i in 0..arr.size-1){
if (i%position==0){
strBuilder.append(characters)
}
strBuilder.append(arr[i])
}
strBuilder.toString()
}else{
pattern
}
}
注意:本题不能使用DecimalFormat和NumberFormat
拜托,任何人都可以帮助我。谢谢。
试试这个
val str = "ABCD"
val prefix = "_"
val position = 3
val result = StringBuilder()
val offset = position - str.length % position
for (i in str.indices) {
if (i != 0 && (i + offset) % position == 0) {
result.append(prefix)
}
result.append(str[i])
}
println(result)
我觉得reverse
字符串然后循环,在某个位置加前缀然后reverse
再次解决这个问题
我认为完成此操作的最简洁方法是使用 chunked() and joinToString() 的组合。不幸的是,stdlib 只提供了 chunked()
从左边开始计数,我们这里需要从右边开始计数。不过,我认为实施 chunkedRight()
并将其与 joinToString()
一起使用会更干净。
fun CharSequence.chunkedRight(size: Int): List<String> {
if (isEmpty()) return emptyList()
val fullChunks = length / size
val firstSize = length - fullChunks * size
// capacity may be too big by one - no problem here
return ArrayList<String>(fullChunks + 1).apply {
if (firstSize > 0) {
add(substring(0, firstSize))
}
(firstSize until length step size).forEach {
add(substring(it, it + size))
}
}
}
或者:
fun CharSequence.chunkedRightSequence(size: Int): Sequence<String> {
if (isEmpty()) return emptySequence()
val firstSize = (length - 1) % size + 1
return sequenceOf(substring(0, firstSize)) +
(firstSize until length step size).asSequence()
.map { substring(it, it + size) }
}
然后我们可以这样使用它:
println("ABCDEFGH".chunkedRight(3).joinToString("_"))
println("10000000".chunkedRight(3).joinToString("_"))
println("10000000".chunkedRight(2).joinToString("_"))
或者我们可以为此创建一个专门的函数。
这是一个使用标准 Kotlin 库函数的实现 - 无需处理索引。
fun main() {
println(convert("ABCDEFGH", 3, "_")) // AB_CDE_FGH
println(convert("10000000", 3, "_")) // 10_000_000
println(convert("10000000", 2, "_")) // 10_00_00_00
}
fun convert(input: String, position: Int, separator: String) =
input
// reverse the string
// e.g. HGFEDCBA
.reversed()
// split into chunks
// e.g. [HGF], [EDC], [BA]
.chunked(position)
// join the chunks back into a string, with a separator
// e.g. HGF_EDC_BA
.joinToString(separator)
// un-reverse the string - done!
// e.g. AB_CDE_FGH
.reversed()
从字符串末尾开始计数很重要(您当前的循环从左侧开始)。要进入 'backwards',我已经 reversed the input string. As String is an Iterable I've used chunk to split it into position
sizes, and then 'inserted' the separator using joinToString 在分块列表中。最后,我再次调用 reverse
以撤消初始反转。