2020-03-12 17:52:18 +00:00
|
|
|
|
## externalsort
|
|
|
|
|
|
|
|
|
|
В этой задаче нужно написать однопроходную внешнюю сортировку слиянием.
|
2021-02-26 10:31:17 +00:00
|
|
|
|
Моделируется ситуация, в которой данные расположены на внешних устройствах и суммарно не вмещаются в оперативную память,
|
|
|
|
|
но каждый кусочек по отдельности вмещается.
|
2020-03-12 17:52:18 +00:00
|
|
|
|
|
|
|
|
|
Задача разбита на 3 составные части.
|
|
|
|
|
|
|
|
|
|
#### Reader & writer
|
|
|
|
|
|
|
|
|
|
Реализовать интерфейсы для построчного чтения/записи строк:
|
|
|
|
|
```
|
|
|
|
|
type LineReader interface {
|
|
|
|
|
ReadLine() (string, error)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-12 20:12:36 +00:00
|
|
|
|
type LineWriter interface {
|
2020-03-12 17:52:18 +00:00
|
|
|
|
Write(l string) error
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
и два конструктора:
|
|
|
|
|
```
|
|
|
|
|
func NewReader(r io.Reader) LineReader
|
2020-03-12 20:12:36 +00:00
|
|
|
|
func NewWriter(w io.Writer) LineWriter
|
2020-03-12 17:52:18 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`NewLineReader` оборачивает переданный `io.Reader` в `LineReader`.
|
|
|
|
|
|
|
|
|
|
Вызов `ReadLine` должен читать одну строку.
|
|
|
|
|
Строка имеет произвольную длину.
|
|
|
|
|
Конец строки определяется переводом строки ('\n').
|
|
|
|
|
Непустая последовательность символов после последнего перевода строки также считается строкой.
|
|
|
|
|
|
2020-03-14 14:55:23 +00:00
|
|
|
|
`ReadLine` должен возвращать `io.EOF` при достижении конца файла.
|
2020-03-12 17:52:18 +00:00
|
|
|
|
|
|
|
|
|
#### Merge
|
|
|
|
|
|
|
|
|
|
Функция слияния произвольного количества отсортированных групп строк:
|
|
|
|
|
```
|
2020-03-12 20:12:36 +00:00
|
|
|
|
func Merge(w LineWriter, readers ...LineReader) error
|
2020-03-12 17:52:18 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`Merge` по необходимости читает из reader'ов и пишет во writer.
|
|
|
|
|
|
|
|
|
|
#### Sort
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Sort(w io.Writer, in ...string) error
|
|
|
|
|
```
|
|
|
|
|
|
2021-02-26 10:31:17 +00:00
|
|
|
|
Функция принимает на вход произвольное количество файлов, каждый из которых помещается в оперативную память,
|
2020-03-12 17:52:18 +00:00
|
|
|
|
а также writer для записи результата.
|
|
|
|
|
|
|
|
|
|
Результаты сортировки отдельных файлов можно записывать поверх входных данных.
|
|
|
|
|
|
|
|
|
|
### Ссылки
|
|
|
|
|
|
|
|
|
|
* container/heap: https://golang.org/pkg/container/heap/
|