英文:
How to insert a Character every X Characters in a String in Golang?
问题
目标: 在 Golang 中的字符串中每隔 x 个字符插入一个字符
输入: helloworldhelloworldhelloworld
期望输出: hello-world-hello-world-hello-world
尝试
尝试一
package main
import (
"fmt"
"strings"
)
func main() {
s := "helloworldhelloworldhelloworld"
s = strings.Replace(s, "world", "-", -1)
fmt.Println(s)
}
结果为:hello-hello-hello-
尝试二
- 计算字符数
- 循环
- 如果 X=5,则插入
-
尝试三
- 使用扫描和连接
问题
尝试二和尝试三目前没有包含代码片段的原因是,我还在思考在 Golang 中的字符串中每隔 X 个字符插入一个字符应该使用什么方法。
英文:
Aim: to insert a character every x characters in a string in Golang
Input: helloworldhelloworldhelloworld
Expected Output: hello-world-hello-world-hello-world
Attempts
Attempt one
package main
import (
"fmt"
"strings"
)
func main() {
s := "helloworldhelloworldhelloworld"
s = strings.Replace(s, "world", ",", -1)
fmt.Println(s)
}
results in: hello,hello,hello,
Attempt two
- Count number of characters
- For loop
- If X=5 then insert a
-
Attempt three
- Scan combined with join
Problem
The reason that attempts two and three do not contain code snippets at the moment is that I am still thinking what approach should be used to insert a character every X characters in a string in Golang.
答案1
得分: 10
这个函数只是在每第N个元素之间插入'-'符号。
func insertNth(s string, n int) string {
var buffer bytes.Buffer
var n_1 = n - 1
var l_1 = len(s) - 1
for i, rune := range s {
buffer.WriteRune(rune)
if i % n == n_1 && i != l_1 {
buffer.WriteRune('-')
}
}
return buffer.String()
}
函数的作用是将字符串s中的每第N个元素之间插入'-'符号,并返回修改后的字符串。
英文:
https://play.golang.org/p/HEGbe7radf
This function just inserts '-' each Nth element
func insertNth(s string,n int) string {
var buffer bytes.Buffer
var n_1 = n - 1
var l_1 = len(s) - 1
for i,rune := range s {
buffer.WriteRune(rune)
if i % n == n_1 && i != l_1 {
buffer.WriteRune('-')
}
}
return buffer.String()
}
答案2
得分: 4
我觉得以下解决方案值得一提:
package main
import "fmt"
var s = "helloworldhelloworldhelloworld"
func main() {
for i := 5; i < len(s); i += 6 {
s = s[:i] + "-" + s[i:]
}
fmt.Println(s)
}
链接:https://play.golang.org/p/aMXOTgiNHf
英文:
I feel the following solution is worth mentioning:
package main
import "fmt"
var s = "helloworldhelloworldhelloworld"
func main() {
for i := 5; i < len(s); i += 6 {
s = s[:i] + "-" + s[i:]
}
fmt.Println(s)
}
答案3
得分: 2
根据Go文档,字符串是一个只读的字节切片。考虑到这一点,会出现一个问题,那就是你使用的字符集是什么?你可以在这里看到一些例子,展示了一些奇怪的情况。
尽管存在复杂性,但仍然有一个简单的答案:
s = strings.Replace(s, "hello", "hello-", -1)
s = strings.Replace(s, "world", "world-", -1)
英文:
According to the Go documentation strings are a read only Slice of bytes.. With that in mind there is an issue that comes up. What character set are you using? You can see some examples of where things get weird here and here.
Despite the complexity there still is a simple answer
s = strings.Replace(s, "hello", "hello-", -1)
s = strings.Replace(s, "world", "world-", -1)
答案4
得分: 1
我的翻译:
我的看法:
import (
"fmt"
"regexp"
)
const s = "helloworldhelloworldhelloworld"
func Attempt1(s string) string {
var re = regexp.MustCompile(`(\Bhello|\Bworld)`)
return re.ReplaceAllString(s, "-$1")
}
func Attempt2(s string) string {
const chunkLen = len("hello")
out := make([]rune, len(s)+len(s)/chunkLen)
i, j := 1, 0
for _, c := range s {
out[j] = c
if i == len(s) {
break
}
j++
if i%chunkLen == 0 {
out[j] = '-'
j++
}
i++
}
return string(out)
}
func main() {
fmt.Println(Attempt1(s))
fmt.Println(Attempt2(s))
}
我应该补充说明,虽然可以实现“方法3”——将源字符串拆分为五个字符的块,然后使用“-”字符连接这些块,但仍需要像Attempt2()
一样逐个字符扫描源字符串;因此,如果你仔细看,你会发现存储块列表然后连接它们会进行更多的操作,而没有真正的收益(还会增加内存占用等)。
英文:
My take:
<pre><code>
import (
"fmt"
"regexp"
)
const s = "helloworldhelloworldhelloworld"
func Attempt1(s string) string {
var re = regexp.MustCompile((\Bhello|\Bworld)
)
return re.ReplaceAllString(s, "-$1")
}
func Attempt2(s string) string {
const chunkLen = len("hello")
out := make([]rune, len(s)+len(s)/chunkLen)
i, j := 1, 0
for _, c := range s {
out[j] = c
if i == len(s) {
break
}
j++
if i%chunkLen == 0 {
out[j] = '-'
j++
}
i++
}
return string(out)
}
func main() {
fmt.Println(Attempt1(s))
fmt.Println(Attempt2(s))
}
</code></pre>
I should add that while it would be possible to implement
"approach 3" — that "split the source string in chunks of
five characters then join the chunks using the '-' character" one, —
it would still require scanning the source string rune-by-rune as my Attempt2()
does; so if you squint at it, you'll see that storing
a list of chunks and then joining them is doing more operations for
no real gain (and bigger memory footprint etc).
答案5
得分: 0
如果您知道您的字符串可以被5整除,那么这也可以是一个解决方案。但与其他一些已发布的解决方案相比,效率肯定较低。
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
fmt.Println(InsertEvery5("HelloWorld", "-"))
}
// 仅在 len(str) mod 5 等于 0 时有效
func InsertEvery5(str string, insert string) string {
re := regexp.MustCompile(`.{5}`) // 每5个字符
parts := re.FindAllString(str, -1) // 将字符串分割为5个字符的块。
return strings.Join(parts, insert) // 将字符串重新组合
}
英文:
If you know your string is divisible by 5, then this could also be a solution. Definitely less efficient though than some of the other solutions posted.
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
fmt.Println(InsertEvery5("HelloWorld", "-"))
}
// Only works if len(str) mod 5 is 0
func InsertEvery5(str string, insert string) string {
re := regexp.MustCompile(`.{5}`) // Every 5 chars
parts := re.FindAllString(str, -1) // Split the string into 5 chars blocks.
return strings.Join(parts, insert) // Put the string back together
}
答案6
得分: 0
我的翻译如下:
我的看法是,我需要在长字符串中添加换行符(不止一个字符)来进行换行。
func InsertNewLines(s string, n int) string {
var r = regexp.MustCompile("(.{" + strconv.Itoa(n) + "})")
return r.ReplaceAllString(s, "$1<wbr />")
}
英文:
My take. I needed to add new lines (more than a single character) to long strings to wrap them.
func InsertNewLines(s string, n int) string {
var r = regexp.MustCompile("(.{" + strconv.Itoa(n) + "})")
return r.ReplaceAllString(s, "$1<wbr />")
}
答案7
得分: 0
预先分配内存并使用copy
比迭代每个字符要快。
func insertNthCopy(in, sep string, n int) string {
count := len(in) / n // 分割的行数
split := make([]byte, len(in)+len(sep)*count)
i, s := 0, 0
for ; i < count*n; i, s = i+n, s+n+len(sep) {
copy(split[s:], in[i:i+n])
copy(split[s+n:], sep)
}
copy(split[s:], in[i:]) // 复制剩余的部分(如果有)
return string(split)
}
与提供的示例字符串相比,大约快了六倍:
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
Benchmark_insertNthCopy
Benchmark_insertNthCopy-8 12404311 85.11 ns/op
Benchmark_insertNth
Benchmark_insertNth-8 2269458 524.5 ns/op
英文:
Pre-allocating memory and using copy
is faster than iteration over every single character.
https://go.dev/play/p/NqVYnOJGRLP
func insertNthCopy(in, sep string, n int) string {
count := len(in) / n // amount of lines to split
split := make([]byte, len(in)+len(sep)*count)
i, s := 0, 0
for ; i < count*n; i, s = i+n, s+n+len(sep) {
copy(split[s:], in[i:i+n])
copy(split[s+n:], sep)
}
copy(split[s:], in[i:]) // copy remainder if any
return string(split)
}
About six times faster than the accepted answer with provided sample string:
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
Benchmark_insertNthCopy
Benchmark_insertNthCopy-8 12404311 85.11 ns/op
Benchmark_insertNth
Benchmark_insertNth-8 2269458 524.5 ns/op
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论