Telegram Group & Telegram Channel
Note #27 Evolution of reverse string "Hello, 世界"

4 года назад мне попался интересный вопрос: как же развернуть строку используя Го?! Сложность заключается в том, чтобы не сломать UTF-8 символы которые могут быть в строке. Т.е. если решать в лоб то получим: ��� ,olleH���, а хотелось бы 界世 ,olleH.

В 2009 Russ Cox в девелоперской рассылке golang-nuts [3] предложил решить эту задачку так:
func reverseString(s string) string {
n := 0
rune := make([]rune, len(s))
for _, r := range s {
rune[n] = r
n++
}
rune = rune[0:n]
// Reverse
for i := 0; i < n/2; i++ {
rune[i], rune[n-1-i] = rune[n-1-i], rune[i]
}
// Convert back to UTF-8.
return string(rune)
}

Немного громоздко, но все же работает и сейчас (оставил оригинальное решение, понятное дело, что можно улучшить, Russ писал думаю пару минут):
>> fmt.Println(reverseString("世Hello, 世"))
>> 世 ,olleH世

Если не много упростить, используя тот факт, что строку можно конвертировать на прямую в []rune без дополнительного цикла [1]:
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}

Идея та же, но код получился чуть более лаконичный.

Самое быстрое решение и не самое лаконичное:
func ReverseFast(s string) string {
size := len(s)
buf := make([]byte, size)
for start := 0; start < size; {
r, n := utf8.DecodeRuneInString(s[start:])
start += n
utf8.EncodeRune(buf[size-start:], r)
}
return string(buf)
}


И самый интересный на мой взгляд вариант с помощью defer, рекомендую остановиться и подумать что же тут происходит на самом деле :
func ReverseClosure(s string) (result string) {
for _, v := range s {
defer func(r rune) { result += string(r) }(v)
}
return
}

Это не самое быстрое решение, но оно показывает как используя замыкание мы сохраняем промежуточное значение в переменной result, для дальнейшего использования каждого defer вызова функции :)

P.S. В качестве упражнения я рекомендую реализовать func reverse(s string) для так называемых “combining characters”. Те чтобы покрыть такой кейс:
"as⃝df̅" превратить в "f̅ds⃝a"

Links:
[1] https://github.com/golang/example/blob/master/stringutil/reverse.go
[2] https://golang.org/pkg/unicode/utf8/#DecodeRuneInString
[3] https://groups.google.com/forum/#!topic/golang-nuts/oPuBaYJ17t4
[4] http://rosettacode.org/wiki/Reverse_a_string



tg-me.com/golang_for_two/52
Create:
Last Update:

Note #27 Evolution of reverse string "Hello, 世界"

4 года назад мне попался интересный вопрос: как же развернуть строку используя Го?! Сложность заключается в том, чтобы не сломать UTF-8 символы которые могут быть в строке. Т.е. если решать в лоб то получим: ��� ,olleH���, а хотелось бы 界世 ,olleH.

В 2009 Russ Cox в девелоперской рассылке golang-nuts [3] предложил решить эту задачку так:

func reverseString(s string) string {
n := 0
rune := make([]rune, len(s))
for _, r := range s {
rune[n] = r
n++
}
rune = rune[0:n]
// Reverse
for i := 0; i < n/2; i++ {
rune[i], rune[n-1-i] = rune[n-1-i], rune[i]
}
// Convert back to UTF-8.
return string(rune)
}

Немного громоздко, но все же работает и сейчас (оставил оригинальное решение, понятное дело, что можно улучшить, Russ писал думаю пару минут):
>> fmt.Println(reverseString("世Hello, 世"))
>> 世 ,olleH世

Если не много упростить, используя тот факт, что строку можно конвертировать на прямую в []rune без дополнительного цикла [1]:
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}

Идея та же, но код получился чуть более лаконичный.

Самое быстрое решение и не самое лаконичное:
func ReverseFast(s string) string {
size := len(s)
buf := make([]byte, size)
for start := 0; start < size; {
r, n := utf8.DecodeRuneInString(s[start:])
start += n
utf8.EncodeRune(buf[size-start:], r)
}
return string(buf)
}


И самый интересный на мой взгляд вариант с помощью defer, рекомендую остановиться и подумать что же тут происходит на самом деле :
func ReverseClosure(s string) (result string) {
for _, v := range s {
defer func(r rune) { result += string(r) }(v)
}
return
}

Это не самое быстрое решение, но оно показывает как используя замыкание мы сохраняем промежуточное значение в переменной result, для дальнейшего использования каждого defer вызова функции :)

P.S. В качестве упражнения я рекомендую реализовать func reverse(s string) для так называемых “combining characters”. Те чтобы покрыть такой кейс:
"as⃝df̅" превратить в "f̅ds⃝a"

Links:
[1] https://github.com/golang/example/blob/master/stringutil/reverse.go
[2] https://golang.org/pkg/unicode/utf8/#DecodeRuneInString
[3] https://groups.google.com/forum/#!topic/golang-nuts/oPuBaYJ17t4
[4] http://rosettacode.org/wiki/Reverse_a_string

BY 🇺🇦 Go for two :)


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/golang_for_two/52

View MORE
Open in Telegram


🇺🇦 Go на двоих Telegram | DID YOU KNOW?

Date: |

Telegram and Signal Havens for Right-Wing Extremists

Since the violent storming of Capitol Hill and subsequent ban of former U.S. President Donald Trump from Facebook and Twitter, the removal of Parler from Amazon’s servers, and the de-platforming of incendiary right-wing content, messaging services Telegram and Signal have seen a deluge of new users. In January alone, Telegram reported 90 million new accounts. Its founder, Pavel Durov, described this as “the largest digital migration in human history.” Signal reportedly doubled its user base to 40 million people and became the most downloaded app in 70 countries. The two services rely on encryption to protect the privacy of user communication, which has made them popular with protesters seeking to conceal their identities against repressive governments in places like Belarus, Hong Kong, and Iran. But the same encryption technology has also made them a favored communication tool for criminals and terrorist groups, including al Qaeda and the Islamic State.

Dump Scam in Leaked Telegram Chat

A leaked Telegram discussion by 50 so-called crypto influencers has exposed the extraordinary steps they take in order to profit on the back off unsuspecting defi investors. According to a leaked screenshot of the chat, an elaborate plan to defraud defi investors using the worthless “$Few” tokens had been hatched. $Few tokens would be airdropped to some of the influencers who in turn promoted these to unsuspecting followers on Twitter.

🇺🇦 Go на двоих from us


Telegram 🇺🇦 Go for two :)
FROM USA