19434


Golangで文字列、例えばAAAAAAの間にABABABABABABのように別の文字列を挿入したいです。もちろん、for文で回して実装できますが、スピードを求める場合利用できる関数などはありますか。  
自分は`strings.FieldsFunc`が使えると考えやってみましたが、できませんでした。もしあれば教えて下さい。  
<https://play.golang.org/p/kAcWCHBPfK>


CC BY-SA 3.0
2015-11-29T09:32:16.357
19432
2015-11-30T02:04:07.510
7232
question
go
Goで文字列の間と最後に文字を挿入したい


`regexp.ReplaceAllString()` を使ってみました(`A` を挟んでいます)。

[code]

    package main
    
    import (
        "fmt"
        "regexp"
    )
    
    func main() {
        a := "abcdefghijklmnopqrstuvwxyz"
        re, _ := regexp.Compile(`(.)`)
        replaced := re.ReplaceAllString(a, "${1}A")
    
        fmt.Println(replaced)
    }
    
[/code]


CC BY-SA 3.0
2015-11-29T09:58:17.697
19434
2015-11-29T09:58:17.697
19432
answer


スピード重視ならば、正規表現を使わずにunicode/utf8を使って自前でやるというのも、選択肢になります。日本語への対応が要らなければ、[]byteを直接いじるのでも良いでしょう。

[code]

    package main
    
    import (
        "fmt"
        "unicode/utf8"
    )
    
    func InsertEach(s string, t string) string {
        ls, lt := len(s), len(t)
        r := make([]byte, 0, (lt+1)*ls)
        for i, w := 0, 0; i < ls; i += w {
            _, w = utf8.DecodeRuneInString(s[i:])
            if len(r) > 0 {
                r = append(r, ([]byte(t))...)
            }
            r = append(r, s[i:i+w]...)
        }
        return string(r)
    }
    
    func main() {
        fmt.Println(InsertEach("abcdefghijklmnopqrstuvwxyz", "A"))
        fmt.Println(InsertEach("あいおえおかきくけこさしすせそ", ","))
    }
    
[/code]

出力

[code]

    aAbAcAdAeAfAgAhAiAjAkAlAmAnAoApAqArAsAtAuAvAwAxAyAz
    あ,い,お,え,お,か,き,く,け,こ,さ,し,す,せ,そ
    
[/code]


CC BY-SA 3.0
2015-11-29T18:32:43.633
19446
2015-11-29T18:32:43.633
208
19432
answer


KoRoN さんの別解ですが。

[code]

    package main
    
    import (
        "bytes"
        "fmt"
    )
    
    func InsertEach(s string, t string) string {
        var b bytes.Buffer
        for _, r := range s {
            if b.Len() > 0 {
                b.WriteString(t)
            }
            b.WriteRune(r)
        }
        return b.String()
    }
    
    func main() {
        fmt.Println(InsertEach("abcdefghijklmnopqrstuvwxyz", "A"))
        fmt.Println(InsertEach("あいおえおかきくけこさしすせそ", "～"))
    }
    
[/code]

for-range string はコピーが発生しない点、bytes.Buffer を使っているのでアロケーションを最小限に抑えられる点を重視してみました。


CC BY-SA 3.0
2015-11-30T01:53:39.170
19454
2015-11-30T02:04:07.510
2015-11-30T02:04:07.510
440
440
19432
answer