Алгоритмсозӣ ва барномасозӣ дар забони Go

Китоби таълимии забони Go барои мактабиён, донишҷӯён ва омӯзгорон: аз алгоритм ва блок-схемаҳо то веб-сервер ва боти Телеграм. Таҷдиди китоби А. П. Назаров «Алгоритмсозӣ ва барномасозӣ дар забони Бейсик» (2009).
Агенти Зеҳнӣ · 26 октябри 2026 · 15 саҳифа
Боби 7. Массивҳо ва буришҳо
Боби 7. Массивҳо ва буришҳо
То ин дам мо дар ҳар як тағйирёбанда танҳо як қиматро (як адад ё як сатр) нигоҳ медоштем. Аммо агар ба шумо лозим ояд, ки баҳоҳои 30 хонандаи як синф, ҳарорати ҳавои 365 рӯзи сол ё нархи 1000 маҳсулотро дар барнома нигоҳ доред, эълон кардани 1000 тағйирёбандаи алоҳида корро душвор мекунад! Барои нигоҳ доштани маҷмӯаи додаҳои ҳамнавъ дар забони Go массивҳо ва хусусан буришҳо (slices) истифода мешаванд. Дар ин боб шумо тарзи кор бо онҳоро меомӯзед.
Дар ин боб меомӯзем
- Массиви статикӣ чист ва чӣ тавр эълон мешавад.
- Буриш (slice) чист ва чаро он дар Go нисбат ба массиви статикӣ бештар истифода мешавад.
- Эҷоди буришҳо бо ёрии функсияи
makeва илова кардани унсурҳо боappend. - Ҷудо кардани қисми буриш (
s[a:b]), дарозӣ (len) ва ғунҷоиш (cap), массиви умумии зери буришҳо. - Хондани унсурҳо бо индекси онҳо (индексатсия аз 0).
- Коркарди қулайи унсурҳо бо ёрии даври
for range. - Алгоритмҳои асосӣ: ёфтани калонтарин ва хурдтарин унсур (min/max), ҳисоби қимати миёна ва филтр кардан.
- Мураттабсозӣ (sorting): алгоритми «ҳубобча» ва бастаи стандартии
slices. - Шиносоӣ бо массивҳои дученака (матритсаҳо).
Массиви статикӣ дар Go
Массив (array) — ин маҷмӯи пайдарпайи унсурҳои якхела мебошад, ки андозаи он пешакӣ муайян шудааст ва дар рафти кори барнома дигар тағйир намеёбад.
Эълони массиви дорои 5 адади бутун:
var a [5]int
Ҳангоми эълон, ҳамаи 5 унсури массив қимати пешфарзи худро (0) мегиранд.
Шумо метавонед ба массив дарҳол қимат диҳед:
bahoho := [5]int{5, 4, 5, 3, 4}
Индексгузорӣ (рақамгузории унсурҳо) аз сифр сар мешавад!
Дар аксари забонҳои муосири барномасозӣ, аз ҷумла дар Go, рақамгузории унсурҳои массив на аз 1, балки аз 0 сар мешавад:
- Унсури якум:
a[0] - Унсури дуюм:
a[1] - Унсури охирин (барои массиви 5-унсура):
a[4]
package main
import "fmt"
func main() {
var a [3]string
a[0] = "Тоҷикистон"
a[1] = "Ватан"
a[2] = "Модар"
fmt.Println(a[0], a[1], a[2])
fmt.Println("Дарозии массив:", len(a)) // len(a) баробари 3 мешавад
}
Буришҳо (Slices): сохтори асосии Go
Гарчанде ки массивҳои статикӣ вуҷуд доранд, дар барномаҳои амалии Go барномасозон қариб ҳамеша буришҳо (slices)-ро истифода мебаранд.
Чаро? Чунки буришҳо андозаи динамикӣ (тағйирёбанда) доранд! Шумо метавонед дар вақти кори барнома ба буриш унсурҳои нав илова кунед ё андозаи онро калону хурд созед.
Буриш мисли массив эълон мешавад, вале дар дохили қавсҳои чоркунҷа рақам навишта намешавад:
var nomho []string // буриши холӣ
adadho := []int{10, 20, 30, 40, 50} // буриш бо қиматҳои ибтидоӣ
Эҷоди буриш бо функсияи make
Агар шумо донед, ки ба чанд унсур ниёз доред, аммо қиматҳоро баъдтар ворид мекунед, функсияи make-ро истифода баред:
// Буриши дорои 5 адади float64 бо қимати ибтидоии 0.0
b := make([]float64, 5)
Илова кардани унсурҳо: функсияи append
Яке аз муҳимтарин ва серистифодатарин функсияҳо дар Go — ин append мебошад. Он унсурҳои навро ба охири буриш илова мекунад ва буриши навро бармегардонад:
package main
import "fmt"
func main() {
var adadho []int // буриши холӣ (дарозӣ = 0)
adadho = append(adadho, 10)
adadho = append(adadho, 25)
adadho = append(adadho, 40)
fmt.Println("Унсурҳои буриш:", adadho)
fmt.Println("Шумораи унсурҳо:", len(adadho))
}
Натиҷа:
Унсурҳои буриш: [10 25 40]
Шумораи унсурҳо: 3
Қисми буриш: s[a:b], len ва cap
Аз буриш (ё массив) метавон қисми онро ҷудо кард. Ифодаи s[a:b] унсурҳоро аз индекси a то индекси b (худи b дохил намешавад) мегирад:
s := []int{10, 20, 30, 40, 50}
fmt.Println(s[1:4]) // [20 30 40]
fmt.Println(s[:2]) // [10 20] — аз аввал то индекси 2
fmt.Println(s[3:]) // [40 50] — аз индекси 3 то охир
fmt.Println(s[:]) // [10 20 30 40 50] — тамоми буриш
Дар мисоли боло s[7] бо хатои index out of range ва s[2:9] бо хатои slice bounds out of range қатъ мешаванд. Индекси унсур бояд аз len(s) хурд бошад; ҳангоми сохтани зербуриш ҳадди болоӣ метавонад то cap(s) расад.
Буриш дар асл чист?
Буриш худаш унсурҳоро нигоҳ намедорад. Он танҳо ба як массиви зеринӣ (underlying array) «равзана» мекушояд ва се чизро медонад:
- нишондиҳанда ба аввалин унсури худ дар массив;
- дарозӣ —
len(s), яъне шумораи унсурҳое, ки буриш нишон медиҳад; - ғунҷоиш —
cap(s), яъне шумораи ҷойҳо аз аввали буриш то охири массиви зеринӣ.
Аз ин як хулосаи муҳим бармеояд: якчанд буриш метавонанд аз як массиви умумӣ истифода баранд, ва тағйири унсур тавассути як буриш дар дигараш низ дида мешавад:
package main
import "fmt"
func main() {
a := []int{10, 20, 30, 40, 50}
b := a[1:4] // унсурҳои бо индексҳои 1, 2, 3
fmt.Println("b =", b, "len =", len(b), "cap =", cap(b))
b[0] = 99 // a[1] низ тағйир меёбад!
fmt.Println("a =", a)
b = append(b, 77) // ғунҷоиш ҳаст, бинобар ин a[4] иваз мешавад!
fmt.Println("a =", a)
fmt.Println("b =", b)
}
Натиҷа:
b = [20 30 40] len = 3 cap = 4
a = [10 99 30 40 50]
a = [10 99 30 40 77]
b = [99 30 40 77]
Агар ба шумо нусхаи мустақил лозим бошад, ки бо буриши аслӣ алоқа надошта бошад, онро бо slices.Clone (аз бастаи slices) ё бо функсияи дарунсохти copy созед:
nusxa := make([]int, len(a))
copy(nusxa, a) // акнун тағйири nusxa ба a таъсир намерасонад
Чаро натиҷаи append-ро бояд аз нав нигоҳ дорем?
Ҳангоми илова кардани як унсур бо append, агар дар массиви зеринӣ ҷойи холӣ (len < cap) бошад, унсур ба ҳамон массив навишта мешавад. Агар ҷой набошад, Go массиви калонтар ҷудо карда, унсурҳои пешинаро ба он нусхабардорӣ мекунад. append буришеро бо дарозии нав бармегардонад; барои истифодаи натиҷа онро ба тағйирёбанда бахшидан лозим аст:
adadho = append(adadho, 60) // дуруст
append(adadho, 60) // хато: Go натиҷаи истифоданашударо қабул намекунад
Агар шумораи тахминии унсурҳо пешакӣ маълум бошад, ғунҷоишро бо параметри сеюми make муайян кардан мумкин аст. Масалан, make([]int, 0, 1000) буриши холие месозад, ки то 1000 унсурро бе ҷудо кардани массиви нав қабул мекунад.
Даври махсуси for range
Барои гузаштан аз рӯи тамоми унсурҳои массив ё буриш, Go як тарзи бениҳоят қулай дорад, ки бо ёрии калимаи калидии range кор мекунад:
package main
import "fmt"
func main() {
shahrho := []string{"Душанбе", "Хуҷанд", "Бохтар", "Кӯлоб"}
for indeks, shahr := range shahrho {
fmt.Printf("Индекси %d: %s\n", indeks, shahr)
}
}
Натиҷа:
Индекси 0: Душанбе
Индекси 1: Хуҷанд
Индекси 2: Бохтар
Индекси 3: Кӯлоб
Агар ба шумо индекси унсур даркор набошад, метавонед ба ҷойи он аломати зерхатро (_) гузоред, то Go хато эълон накунад:
for _, shahr := range shahrho {
fmt.Println(shahr)
}
Алгоритмҳои бунёдии коркарди массивҳо
Биёед чанд масъалаи муҳимро аз китоби таълимӣ бо истифода аз буришҳои Go ҳал кунем:
Масъалаи 1. Ёфтани қимати калонтарин (max) ва хурдтарин (min)
package main
import "fmt"
func main() {
a := []int{23, -5, 18, 92, 4, -15, 67, 33}
khurdtarin := a[0]
kalontarin := a[0]
for _, v := range a {
if v < khurdtarin {
khurdtarin = v
}
if v > kalontarin {
kalontarin = v
}
}
fmt.Println("Массиви додашуда:", a)
fmt.Printf("Хурдтарин унсур (min): %d\n", khurdtarin)
fmt.Printf("Калонтарин унсур (max): %d\n", kalontarin)
}
Натиҷа:
Массиви додашуда: [23 -5 18 92 4 -15 67 33]
Хурдтарин унсур (min): -15
Калонтарин унсур (max): 92
[!NOTE] Мо тағйирёбандаҳоро қасдан
minваmaxномгузорӣ накардем: аз Go 1.21 инҷониб инҳо номи функсияҳои дарунсохт мебошанд (масалан,min(3, 7, 1)ба1баробар аст) ва эълони тағйирёбанда бо ҳамин ном онҳоро «пӯшида» мегузорад. Барои буриши тайёр дар бастаи стандартииslicesфунксияҳоиslices.Min(a)ваslices.Max(a)низ ҳастанд (ниг. ба «Масъалаи 4» дар поён). Алгоритми дастии боло барои фаҳмидани тарзи кори онҳо муҳим аст.
Масъалаи 2. Ҳисоби қимати миёнаи арифметикии массив
package main
import "fmt"
func main() {
bahoho := []float64{4.5, 5.0, 3.8, 4.2, 5.0, 4.0}
summa := 0.0
for _, b := range bahoho {
summa += b
}
miyon := summa / float64(len(bahoho))
fmt.Printf("Суммаи умумӣ: %.2f\n", summa)
fmt.Printf("Бали миёна: %.2f\n", miyon)
}
Масъалаи 3. Ҷудо кардани ададҳои мусбат ва манфӣ (Филтркунӣ)
Массиви ададҳои ҳақиқӣ дода шудааст. Ду буриши нав тартиб диҳед, ки яке танҳо ададҳои мусбат ва дигаре ададҳои манфиро дар бар гирад:
package main
import "fmt"
func main() {
x := []float64{12.4, -3.1, 0, 7.8, -9.5, 14.0, -1.2}
var musbat []float64
var manfi []float64
for _, v := range x {
if v > 0 {
musbat = append(musbat, v)
} else if v < 0 {
manfi = append(manfi, v)
}
}
fmt.Println("Аслӣ: ", x)
fmt.Println("Мусбат: ", musbat)
fmt.Println("Манфӣ: ", manfi)
}
Масъалаи 4. Мураттабсозии массив
Мураттабсозӣ (sorting) — ҷобаҷо гузоштани унсурҳо бо тартиби афзуншавӣ ё камшавӣ — яке аз масъалаҳои асосии алгоритмсозӣ мебошад. Содатарин алгоритм усули «ҳубобча» (bubble sort) аст: ҳар ду унсури ҳамсояро муқоиса мекунем ва агар тартибашон нодуруст бошад, ҷояшонро иваз мекунем. Пас аз ҳар як гузариш калонтарин унсури боқимонда мисли ҳубобча ба охир «баромада меояд».
package main
import "fmt"
func main() {
a := []int{23, -5, 18, 92, 4, -15, 67, 33}
n := len(a)
for i := 0; i < n-1; i++ {
ivaz := false // оё дар ин гузариш ягон ҷобаҷогузорӣ шуд?
for j := 0; j < n-1-i; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j] // ивази ҷойи ду унсур
ivaz = true
}
}
if !ivaz {
break // ҳеҷ ивазе нашуд — массив аллакай мураттаб аст
}
}
fmt.Println("Мураттабшуда:", a)
}
Натиҷа:
Мураттабшуда: [-15 -5 4 18 23 33 67 92]
Сатри a[j], a[j+1] = a[j+1], a[j] бахшидани ҳамзамони чанд қимат ном дорад: Go аввал ҳар ду қимати тарафи ростро ҳисоб карда, баъд онҳоро ҳамзамон ба тарафи чап мегузорад. Бинобар ин барои иваз кардани ҷойи ду қимат тағйирёбандаи ёрирасон лозим нест.
Алгоритми «ҳубобча» барои омӯзиш хуб аст, аммо барои массивҳои калон суст кор мекунад (тақрибан n² муқоиса). Дар барномаҳои воқеӣ бастаи стандартии slices (Go 1.21+) истифода мешавад, ки алгоритмҳои тезкорро дар бар мегирад:
package main
import (
"fmt"
"slices"
)
func main() {
a := []int{23, -5, 18, 92, 4, -15, 67, 33}
fmt.Println("Хурдтарин:", slices.Min(a))
fmt.Println("Калонтарин:", slices.Max(a))
slices.Sort(a) // мураттабсозӣ бо тартиби афзуншавӣ
fmt.Println("Афзуншаванда:", a)
slices.Reverse(a) // тартиби унсурҳоро чаппа мекунад
fmt.Println("Камшаванда:", a)
// Функсияҳои дарунсохти min ва max барои якчанд қимати алоҳида
fmt.Println(min(7, 3, 9), max(2.5, 8.1))
}
Натиҷа:
Хурдтарин: -15
Калонтарин: 92
Афзуншаванда: [-15 -5 4 18 23 33 67 92]
Камшаванда: [92 67 33 23 18 4 -5 -15]
3 8.1
[!WARNING]
slices.Minваslices.Maxбарои буриши холӣ хатои фавқулодда (panic) медиҳанд, бинобар ин пеш аз истифодаlen(a) > 0будани буришро санҷед. Бастаи кӯҳнаиsort(sort.Ints) низ ҳанӯз кор мекунад, вале дар коди навslices.Sortтавсия дода мешавад.
Массивҳои дученака (Матритсаҳо)
Агар унсурҳои як массив худашон массив бошанд, сохтори дученака ё матритса ҳосил мешавад. Он аз сатрҳо ва сутунҳо иборат аст.
package main
import "fmt"
func main() {
// Матритсаи 3х3 (3 сатр ва 3 сутун)
matritsa := [3][3]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
fmt.Println("Унсури сатри 2, сутуни 3:", matritsa[1][2]) // 6
fmt.Println("Намуди матритса:")
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
fmt.Printf("%3d ", matritsa[i][j])
}
fmt.Println()
}
}
Худатон бисанҷед
7–1. Воридот ба буриш: Барномае нависед, ки аввал аз корбар миқдори ададҳо N-ро пурсад. Сипас бо ёрии даври for ва fmt.Scan ин N ададро аз клавиатура қабул карда, ба буриш дохил кунад ва дар охир буришро ба таври чаппа (аз охир ба аввал) чоп намояд.
7–2. Ҷуфту тоқ: Буриши иборат аз 10 адади бутунро созед. Шумораи ададҳои ҷуфт ва суммаи ададҳои тоқро дар ин буриш ҳисоб кунед.
7–3. Ҷустуҷӯи хаттӣ: Барномае нависед, ки буриши ададҳо ва як адади ҷустуҷӯшавандаи K-ро қабул кунад. Муайян кунед, ки оё адади K дар ин буриш мавҷуд аст ё не? Агар бошад, дар кадом индекс қарор дорад?
7–4. Диагонали асосии матритса: Матритсаи квадратии 3 × 3-ро эълон кунед. Суммаи унсурҳоеро, ки дар диагонали асосии он ҷойгиранд (яъне дар ҷойҳое, ки рақами сатр ба рақами сутун баробар аст: M[0][0], M[1][1], M[2][2]), ҳисоб намоед.
Хулоса
Дар ин боб шумо сохторҳои ҷамъоварии маълумотро дар забони Go аз худ кардед. Фаҳмидед, ки чаро буришҳо (slices) нисбат ба массивҳои андозаашон собит қулайтаранд, функсияи append-ро омӯхтед, дидед, ки буришҳо метавонанд аз як массиви умумӣ истифода баранд, ададҳоро бо алгоритми «ҳубобча» ва бо slices.Sort мураттаб сохтед ва дидед, ки даври for range тарзи хондани рӯйхатҳоро то чӣ андоза сода ва бехатар мегардонад.
Дар боби 8 мо ба кор бо сатрҳо ва рамзҳо (Unicode/Runes) мегузарем ва меомӯзем, ки чӣ тавр забони Go бо матнҳои мураккаб ва ҳарфҳои тоҷикӣ бе хато кор мекунад.

Барномасозӣ
Олами Афсонаҳо
Ахбор
Саломатӣ
Дунё