Реализуйте zip, попарно соединяющую два слайса целых до длины меньшего
Реализуйте zip(s1, s2), возвращающую слайс пар, по одной на индекс, останавливаясь на более коротком входе. Каждая пара — это двухэлементный []int. Пример: zip([]int{1,2,3}, []int{4,5,6,7,8}) → [[1 4] [2 5] [3 6]].
func zip(s1, s2 []int) [][]int {
// ваш код здесь
return nil
}
Допишите реализацию.
Вычислите minLen как меньшую из двух длин, предвыделите результат через make([][]int, 0, minLen), затем пройдите i от 0 до minLen, добавляя []int{s1[i], s2[i]}. Остановка на более коротком предотвращает выход за границы, а предвыделение ёмкости избегает повторного роста. Это O(minLen) по времени.
- ✗Идти до большей длины и индексировать вне границ
- ✗Думать, что индекс слайса вне границ возвращает ноль, а не паникует
- ✗Сплющивать в один слайс вместо построения пар
- →Как сделать вариативную
zip(s ...[]int)для любого числа слайсов? - →Как обобщения (generics) позволят
zipработать со слайсами любого типа элементов?
Решение
Идём до меньшей длины, чтобы не выйти за границы; ёмкость известна заранее.
func zip(s1, s2 []int) [][]int {
minLen := len(s1)
if len(s2) < minLen {
minLen = len(s2)
}
res := make([][]int, 0, minLen)
for i := 0; i < minLen; i++ {
res = append(res, []int{s1[i], s2[i]})
}
return res
}
// zip([]int{1,2,3}, []int{4,5,6,7,8}) -> [[1 4] [2 5] [3 6]]
Индексация s1[i] или s2[i] за пределами длины вызвала бы panic, поэтому цикл идёт ровно до minLen. Предвыделение make(..., 0, minLen) избегает повторных перевыделений при append.
⚠️ Индекс слайса вне границ в Go паникует, а не возвращает ноль, — поэтому идти до большей длины нельзя.