Update utf8 task
This commit is contained in:
parent
f9f60e3656
commit
84d9f411c5
4 changed files with 43 additions and 1 deletions
|
@ -5,9 +5,24 @@
|
||||||
Функция принимает на вход юникодную строку и должна возвращать строку,
|
Функция принимает на вход юникодную строку и должна возвращать строку,
|
||||||
состоящую из тех же юникодных рун, но записанных в обратном порядке.
|
состоящую из тех же юникодных рун, но записанных в обратном порядке.
|
||||||
|
|
||||||
|
Если строка содержит последовательность байт, не образующую корректный utf8, нужно развернуть
|
||||||
|
эту последовательность как отдельные байты.
|
||||||
|
|
||||||
Обратите внимание в тестах, что некоторые графемы распадаются при обращении строки.
|
Обратите внимание в тестах, что некоторые графемы распадаются при обращении строки.
|
||||||
Данный эффект связан с тем, что в юникоде некоторые руны умеют комбинироваться в одну графему.
|
Данный эффект связан с тем, что в юникоде некоторые руны умеют комбинироваться в одну графему.
|
||||||
|
|
||||||
|
Ваша реализация должна быть достаточно эффективна. На нашем бенчмарке в тестовой системе
|
||||||
|
она должна работать не хуже авторского решения. В частности, код должен делать не больше двух
|
||||||
|
аллокаций. Эту функцию можно написать с одной аллокацией, но придётся использовать пакет unsafe.
|
||||||
|
Работу с unsafe мы будем разбирать дальше в курсе.
|
||||||
|
|
||||||
|
```
|
||||||
|
goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
pkg: gitlab.com/slon/shad-go/utf8/reverse
|
||||||
|
BenchmarkReverse-4 395078 2763 ns/op 1792 B/op 2 allocs/op
|
||||||
|
PASS
|
||||||
|
```
|
||||||
### Примеры
|
### Примеры
|
||||||
|
|
||||||
Как запустить все тесты:
|
Как запустить все тесты:
|
||||||
|
|
|
@ -2,6 +2,7 @@ package reverse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -36,9 +37,20 @@ func TestReverse(t *testing.T) {
|
||||||
{input: "🇩🇪", output: "🇪🇩"},
|
{input: "🇩🇪", output: "🇪🇩"},
|
||||||
// NB: Флаг распался. :)
|
// NB: Флаг распался. :)
|
||||||
{input: "🏳️🌈", output: "🌈️🏳"},
|
{input: "🏳️🌈", output: "🌈️🏳"},
|
||||||
|
{input: "\xff\x00\xff\x00", output: "\x00\xff\x00\xff"},
|
||||||
} {
|
} {
|
||||||
t.Run(fmt.Sprintf("#%v: %v", i, tc.input), func(t *testing.T) {
|
t.Run(fmt.Sprintf("#%v: %v", i, tc.input), func(t *testing.T) {
|
||||||
require.Equal(t, tc.output, Reverse(tc.input))
|
require.Equal(t, tc.output, Reverse(tc.input))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkReverse(b *testing.B) {
|
||||||
|
input := strings.Repeat("🙂🙂", 100)
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = Reverse(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
Функция принимает на вход юникодную строку и должна возвращать строку,
|
Функция принимает на вход юникодную строку и должна возвращать строку,
|
||||||
состоящую из тех же символов, но где все подряд идущие группы пробельных символов заменены на ' ' (один обычный пробел).
|
состоящую из тех же символов, но где все подряд идущие группы пробельных символов заменены на ' ' (один обычный пробел).
|
||||||
|
|
||||||
### Примеры
|
Некорректную utf8 последовательность функция должна оставлять без изменений.
|
||||||
|
|
||||||
|
## Примеры
|
||||||
|
|
||||||
Как запустить все тесты:
|
Как запустить все тесты:
|
||||||
|
|
||||||
```
|
```
|
||||||
go test -v ./utf8/spacecollapse/...
|
go test -v ./utf8/spacecollapse/...
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,6 +2,7 @@ package spacecollapse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -21,9 +22,20 @@ func TestCollapseSpaces(t *testing.T) {
|
||||||
{input: "\t*", output: " *"},
|
{input: "\t*", output: " *"},
|
||||||
{input: " \t \t ", output: " "},
|
{input: " \t \t ", output: " "},
|
||||||
{input: " \tx\t ", output: " x "},
|
{input: " \tx\t ", output: " x "},
|
||||||
|
{input: "\xff\x00\xff\x00", output: "\xff\x00\xff\x00"},
|
||||||
} {
|
} {
|
||||||
t.Run(fmt.Sprintf("#%v: %v", i, tc.input), func(t *testing.T) {
|
t.Run(fmt.Sprintf("#%v: %v", i, tc.input), func(t *testing.T) {
|
||||||
require.Equal(t, tc.output, CollapseSpaces(tc.input))
|
require.Equal(t, tc.output, CollapseSpaces(tc.input))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkCollapse(b *testing.B) {
|
||||||
|
input := strings.Repeat("🙂 🙂", 100)
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = CollapseSpaces(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue