Структурированные типы данных. Массивы
Массивы — это фундаментальная структура данных, которая используется повсюду: от алгоритмов рекомендаций в YouTube до обработки пикселей в играх. Разберёмся, как устроен этот механизм, — на Си, Паскале и Python: у каждого примера есть вкладки, выбери свой язык.
Что такое массив и зачем он нужен?
Массив — это структура данных, представляющая собой упорядоченную коллекцию элементов одного типа, каждый из которых идентифицируется своим индексом (номером позиции).
💡 Зачем нужны массивы?
Представь, что тебе нужно обработать результаты 1000 студентов. Создавать 1000 отдельных переменных (score1, score2, ..., score1000) — абсурд. Массив позволяет хранить все данные под одним именем и обращаться к каждому элементу по индексу.
Объявление массива
Массив объявляется так:
тип_данных имя_массива[размер];
имя_массива: array[первый_индекс..последний_индекс] of тип;
имя_списка = [начальное_значение] * размер
Примеры объявления массивов:
int temperatures[365]; // массив из 365 целых чисел (температуры по дням года)
double prices[100]; // массив из 100 вещественных чисел (цены товаров)
char password[20]; // массив из 20 символов (пароль)
var
temperatures: array[1..365] of integer; { 365 целых чисел (температуры по дням года) }
prices: array[1..100] of real; { 100 вещественных чисел (цены товаров) }
password: string[20]; { строка до 20 символов (пароль) }
temperatures = [0] * 365 # 365 целых чисел (температуры по дням года)
prices = [0.0] * 100 # 100 вещественных чисел (цены товаров)
password = "" # строка (пароль)
⚠️ Критически важно!
В Си и Python индексация массивов начинается с 0: первый элемент имеет индекс 0, второй — 1, и так далее; массив из 10 элементов имеет индексы от 0 до 9. В Паскале границы индексов задают при описании, обычно с 1: array[1..10] — индексы от 1 до 10. Поэтому в примерах на Паскале номера элементов на единицу больше.
Инициализация массива
Массив можно инициализировать при объявлении:
int scores[5] = {95, 87, 76, 92, 88};
double weights[] = {65.5, 72.3, 58.1}; // размер определяется автоматически
const
scores: array[1..5] of integer = (95, 87, 76, 92, 88);
weights: array[1..3] of real = (65.5, 72.3, 58.1); { размер указывают явно }
scores = [95, 87, 76, 92, 88]
weights = [65.5, 72.3, 58.1] # размер — len(weights)
Или заполнить в цикле:
int numbers[100];
for (int i = 0; i < 100; i++) {
numbers[i] = i * 2; // заполняем чётными числами
}
var
numbers: array[1..100] of integer;
i: integer;
...
for i := 1 to 100 do
numbers[i] := (i - 1) * 2; { заполняем чётными числами: 0, 2, 4, … }
numbers = [0] * 100
for i in range(100):
numbers[i] = i * 2 # заполняем чётными числами
Основные операции с массивами
Рассмотрим базовые операции, которые выполняются с массивами в подавляющем большинстве задач.
Обработка массива: последовательный доступ к элементам через индексацию
Операция 1📥 Ввод и вывод элементов
Пример: Ввод оценок студента и вывод в обратном порядке.
#include <stdio.h>
int main() {
int grades[5];
printf("Введите 5 оценок:\n");
for (int i = 0; i < 5; i++) {
printf("Оценка %d: ", i + 1);
scanf("%d", &grades[i]);
}
printf("\nОценки в обратном порядке:\n");
for (int i = 4; i >= 0; i--) {
printf("%d ", grades[i]);
}
printf("\n");
return 0;
}
program Grades;
var
grades: array[1..5] of integer;
i: integer;
begin
writeln('Введите 5 оценок:');
for i := 1 to 5 do
begin
write('Оценка ', i, ': ');
readln(grades[i]);
end;
writeln;
writeln('Оценки в обратном порядке:');
for i := 5 downto 1 do
write(grades[i], ' ');
writeln;
end.
grades = [0] * 5
print("Введите 5 оценок:")
for i in range(5):
grades[i] = int(input(f"Оценка {i + 1}: "))
print("\nОценки в обратном порядке:")
for i in range(4, -1, -1):
print(grades[i], end=" ")
print()
Что происходит? Первый цикл for последовательно заполняет массив с индекса 0 до 4. Второй цикл выводит элементы в обратном порядке — с индекса 4 до 0.
🔍 Поиск элемента
Задача: Найти, есть ли в массиве заданное число.
Линейный поиск — самый простой алгоритм: последовательно проверяем каждый элемент.
#include <stdio.h>
int main() {
int data[10] = {23, 45, 12, 67, 34, 89, 21, 56, 78, 90};
int target, found = 0;
printf("Введите число для поиска: ");
scanf("%d", &target);
for (int i = 0; i < 10; i++) {
if (data[i] == target) {
printf("Число %d найдено на позиции %d\n", target, i);
found = 1;
break; // прерываем поиск
}
}
if (!found) {
printf("Число %d не найдено\n", target);
}
return 0;
}
program LinearSearch;
const
data: array[1..10] of integer = (23, 45, 12, 67, 34, 89, 21, 56, 78, 90);
var
target, i: integer;
found: boolean;
begin
write('Введите число для поиска: ');
readln(target);
found := false;
for i := 1 to 10 do
if data[i] = target then
begin
writeln('Число ', target, ' найдено на позиции ', i);
found := true;
break; { прерываем поиск }
end;
if not found then
writeln('Число ', target, ' не найдено');
end.
data = [23, 45, 12, 67, 34, 89, 21, 56, 78, 90]
target = int(input("Введите число для поиска: "))
found = False
for i in range(10):
if data[i] == target:
print(f"Число {target} найдено на позиции {i}")
found = True
break # прерываем поиск
if not found:
print(f"Число {target} не найдено")
Анализ сложности: В худшем случае (элемент в конце или отсутствует) нужно проверить все n элементов. Сложность: O(n) — линейная.
Операция 3📊 Поиск максимума и минимума
Подход: Принимаем первый элемент за текущий максимум/минимум, затем сравниваем с ним все остальные элементы.
#include <stdio.h>
int main() {
int numbers[8] = {42, 15, 73, 8, 91, 27, 64, 35};
int max = numbers[0];
int min = numbers[0];
int max_index = 0;
int min_index = 0;
for (int i = 1; i < 8; i++) {
if (numbers[i] > max) {
max = numbers[i];
max_index = i;
}
if (numbers[i] < min) {
min = numbers[i];
min_index = i;
}
}
printf("Максимум: %d (индекс %d)\n", max, max_index);
printf("Минимум: %d (индекс %d)\n", min, min_index);
return 0;
}
program MinMax;
const
numbers: array[1..8] of integer = (42, 15, 73, 8, 91, 27, 64, 35);
var
i, max, min, max_index, min_index: integer;
begin
max := numbers[1];
min := numbers[1];
max_index := 1;
min_index := 1;
for i := 2 to 8 do
begin
if numbers[i] > max then
begin
max := numbers[i];
max_index := i;
end;
if numbers[i] < min then
begin
min := numbers[i];
min_index := i;
end;
end;
writeln('Максимум: ', max, ' (индекс ', max_index, ')');
writeln('Минимум: ', min, ' (индекс ', min_index, ')');
end.
numbers = [42, 15, 73, 8, 91, 27, 64, 35]
biggest = numbers[0]
smallest = numbers[0]
max_index = 0
min_index = 0
for i in range(1, 8):
if numbers[i] > biggest:
biggest = numbers[i]
max_index = i
if numbers[i] < smallest:
smallest = numbers[i]
min_index = i
print(f"Максимум: {biggest} (индекс {max_index})")
print(f"Минимум: {smallest} (индекс {min_index})")
Почему начинаем с i=1? Потому что numbers[0] уже стал начальным значением для max и min. Это классическая оптимизация.
Модификация массивов: вставка и удаление
Рассмотрим операции, которые изменяют структуру массива.
Операции вставки и удаления: реорганизация элементов массива
Удаление элемента
Задача: Удалить элемент с индексом k и сдвинуть все последующие элементы влево.
Логика: Элементы с индексами k+1, k+2, ..., n-1 перемещаются на позиции k, k+1, ..., n-2.
#include <stdio.h>
int main() {
int arr[7] = {10, 20, 30, 40, 50, 60, 70};
int n = 7; // текущий размер массива
int k = 3; // индекс удаляемого элемента
printf("Массив до удаления:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Сдвигаем элементы влево
for (int i = k; i < n - 1; i++) {
arr[i] = arr[i + 1];
}
n--; // уменьшаем размер
printf("Массив после удаления элемента с индексом %d:\n", k);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
program DeleteElement;
var
arr: array[1..7] of integer;
n, k, i: integer;
begin
for i := 1 to 7 do
arr[i] := i * 10; { 10 20 30 40 50 60 70 }
n := 7; { текущий размер массива }
k := 4; { номер удаляемого элемента: в Паскале индексы с 1, это число 40 }
writeln('Массив до удаления:');
for i := 1 to n do
write(arr[i], ' ');
writeln;
{ сдвигаем элементы влево }
for i := k to n - 1 do
arr[i] := arr[i + 1];
n := n - 1; { уменьшаем размер }
writeln('Массив после удаления элемента с индексом ', k, ':');
for i := 1 to n do
write(arr[i], ' ');
writeln;
end.
arr = [10, 20, 30, 40, 50, 60, 70]
n = 7 # текущий размер массива
k = 3 # индекс удаляемого элемента
print("Массив до удаления:")
print(*arr[:n])
# сдвигаем элементы влево
for i in range(k, n - 1):
arr[i] = arr[i + 1]
n = n - 1 # уменьшаем размер
print(f"Массив после удаления элемента с индексом {k}:")
print(*arr[:n])
# в Python то же самое делает готовая команда arr.pop(k)
Результат: 10 20 30 50 60 70 — элемент 40 (индекс 3) удалён.
Вставка элемента
Задача: Вставить новое значение на позицию с индексом k.
Логика: Элементы с индексами k, k+1, ..., n-1 сдвигаются вправо на позиции k+1, k+2, ..., n.
⚠️ Критично!
Сдвиг должен идти справа налево, иначе данные перезапишутся!
#include <stdio.h>
int main() {
int arr[10] = {10, 20, 30, 40, 50, 60, 70}; // объявляем с запасом
int n = 7; // текущий размер
int k = 3; // позиция вставки
int value = 35; // вставляемое значение
printf("Массив до вставки:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Сдвигаем элементы вправо (ВАЖНО: справа налево!)
for (int i = n; i > k; i--) {
arr[i] = arr[i - 1];
}
arr[k] = value;
n++;
printf("Массив после вставки %d на позицию %d:\n", value, k);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
program InsertElement;
var
arr: array[1..10] of integer; { объявляем с запасом }
n, k, value, i: integer;
begin
for i := 1 to 7 do
arr[i] := i * 10; { 10 20 30 40 50 60 70 }
n := 7; { текущий размер }
k := 4; { позиция вставки: в Паскале индексы с 1 }
value := 35; { вставляемое значение }
writeln('Массив до вставки:');
for i := 1 to n do
write(arr[i], ' ');
writeln;
{ сдвигаем элементы вправо (ВАЖНО: справа налево!) }
for i := n + 1 downto k + 1 do
arr[i] := arr[i - 1];
arr[k] := value;
n := n + 1;
writeln('Массив после вставки ', value, ' на позицию ', k, ':');
for i := 1 to n do
write(arr[i], ' ');
writeln;
end.
arr = [10, 20, 30, 40, 50, 60, 70, 0, 0, 0] # с запасом
n = 7 # текущий размер
k = 3 # позиция вставки
value = 35 # вставляемое значение
print("Массив до вставки:")
print(*arr[:n])
# сдвигаем элементы вправо (ВАЖНО: справа налево!)
for i in range(n, k, -1):
arr[i] = arr[i - 1]
arr[k] = value
n = n + 1
print(f"Массив после вставки {value} на позицию {k}:")
print(*arr[:n])
# в Python список растёт сам: то же делает arr.insert(k, value)
Результат: 10 20 30 35 40 50 60 70
Реверс массива
Задача: Перевернуть массив (первый элемент становится последним, и так далее).
Алгоритм: Меняем местами элементы с индексами i и n-1-i, где i идёт от 0 до n/2.
#include <stdio.h>
int main() {
int arr[6] = {1, 2, 3, 4, 5, 6};
int n = 6;
printf("Исходный массив: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Реверс
for (int i = 0; i < n / 2; i++) {
int temp = arr[i];
arr[i] = arr[n - 1 - i];
arr[n - 1 - i] = temp;
}
printf("Перевёрнутый массив: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
program ReverseArray;
const
n = 6;
var
arr: array[1..n] of integer;
i, temp: integer;
begin
for i := 1 to n do
arr[i] := i; { 1 2 3 4 5 6 }
write('Исходный массив: ');
for i := 1 to n do
write(arr[i], ' ');
writeln;
{ реверс }
for i := 1 to n div 2 do
begin
temp := arr[i];
arr[i] := arr[n + 1 - i];
arr[n + 1 - i] := temp;
end;
write('Перевёрнутый массив: ');
for i := 1 to n do
write(arr[i], ' ');
writeln;
end.
arr = [1, 2, 3, 4, 5, 6]
n = 6
print("Исходный массив:", *arr)
# реверс
for i in range(n // 2):
temp = arr[i]
arr[i] = arr[n - 1 - i]
arr[n - 1 - i] = temp
print("Перевёрнутый массив:", *arr)
Результат: 6 5 4 3 2 1
💡 Почему n/2?
Если массив содержит 6 элементов, достаточно 3 обменов: (0↔5), (1↔4), (2↔3). Центральный элемент (если n нечётное) остаётся на месте автоматически.
Сортировка массивов
Зачем сортировать? Упорядоченные данные обрабатываются эффективнее. Например, двоичный поиск в отсортированном массиве имеет сложность O(log n) вместо O(n).
Сортировка: упорядочивание хаотичных данных в структурированную последовательность
Алгоритм 1💧 Сортировка пузырьком (Bubble Sort)
Принцип: Сравниваем соседние элементы и меняем их местами, если они в неправильном порядке. "Тяжёлые" элементы "тонут" вниз, "лёгкие" "всплывают" вверх.
#include <stdio.h>
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Обмен элементов
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int data[6] = {64, 34, 25, 12, 22, 11};
int n = 6;
printf("До сортировки: ");
for (int i = 0; i < n; i++) printf("%d ", data[i]);
printf("\n");
bubbleSort(data, n);
printf("После сортировки: ");
for (int i = 0; i < n; i++) printf("%d ", data[i]);
printf("\n");
return 0;
}
program BubbleSort;
type
TArr = array[1..6] of integer;
var
data: TArr;
i: integer;
procedure bubbleSort(var arr: TArr; n: integer);
var
i, j, temp: integer;
begin
for i := 1 to n - 1 do
for j := 1 to n - i do
if arr[j] > arr[j + 1] then
begin
{ обмен элементов }
temp := arr[j];
arr[j] := arr[j + 1];
arr[j + 1] := temp;
end;
end;
begin
data[1] := 64; data[2] := 34; data[3] := 25;
data[4] := 12; data[5] := 22; data[6] := 11;
write('До сортировки: ');
for i := 1 to 6 do write(data[i], ' ');
writeln;
bubbleSort(data, 6);
write('После сортировки: ');
for i := 1 to 6 do write(data[i], ' ');
writeln;
end.
def bubble_sort(arr, n):
for i in range(n - 1):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
# обмен элементов
temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
data = [64, 34, 25, 12, 22, 11]
print("До сортировки:", *data)
bubble_sort(data, 6)
print("После сортировки:", *data)
Анализ:
- Внешний цикл (
i): n-1 проход - Внутренний цикл (
j): на каждом проходе сравниваем всё меньше элементов - Сложность: O(n²) — квадратичная
Почему n-i-1? После каждого прохода самый большой элемент оказывается в конце, его больше не нужно проверять.
🎯 Сортировка выбором (Selection Sort)
Принцип: Находим минимальный элемент в неотсортированной части массива и меняем его местами с первым неотсортированным элементом.
#include <stdio.h>
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int min_index = i;
// Находим индекс минимального элемента
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min_index]) {
min_index = j;
}
}
// Обмен
if (min_index != i) {
int temp = arr[i];
arr[i] = arr[min_index];
arr[min_index] = temp;
}
}
}
int main() {
int data[6] = {64, 25, 12, 22, 11, 34};
int n = 6;
printf("До сортировки: ");
for (int i = 0; i < n; i++) printf("%d ", data[i]);
printf("\n");
selectionSort(data, n);
printf("После сортировки: ");
for (int i = 0; i < n; i++) printf("%d ", data[i]);
printf("\n");
return 0;
}
program SelectionSort;
type
TArr = array[1..6] of integer;
var
data: TArr;
i: integer;
procedure selectionSort(var arr: TArr; n: integer);
var
i, j, min_index, temp: integer;
begin
for i := 1 to n - 1 do
begin
min_index := i;
{ находим индекс минимального элемента }
for j := i + 1 to n do
if arr[j] < arr[min_index] then
min_index := j;
{ обмен }
if min_index <> i then
begin
temp := arr[i];
arr[i] := arr[min_index];
arr[min_index] := temp;
end;
end;
end;
begin
data[1] := 64; data[2] := 25; data[3] := 12;
data[4] := 22; data[5] := 11; data[6] := 34;
write('До сортировки: ');
for i := 1 to 6 do write(data[i], ' ');
writeln;
selectionSort(data, 6);
write('После сортировки: ');
for i := 1 to 6 do write(data[i], ' ');
writeln;
end.
def selection_sort(arr, n):
for i in range(n - 1):
min_index = i
# находим индекс минимального элемента
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
min_index = j
# обмен
if min_index != i:
temp = arr[i]
arr[i] = arr[min_index]
arr[min_index] = temp
data = [64, 25, 12, 22, 11, 34]
print("До сортировки:", *data)
selection_sort(data, 6)
print("После сортировки:", *data)
Преимущество: Минимальное количество обменов — всего n-1. Полезно, когда операция обмена дорогая.
Сложность: O(n²) по сравнениям, O(n) по обменам.
Практическое применение: реальные задачи
Рассмотрим задачи, которые демонстрируют практическую ценность работы с массивами.
Эффективность алгоритмов: от линейного к логарифмическому поиску
🌡️ Задача 1: Анализ метеоданных
Условие: Даны температуры за 30 дней июня. Найти среднюю температуру и дни с отклонением более чем на 5°C.
#include <stdio.h>
int main() {
double temp[30];
double sum = 0, avg;
printf("Введите температуры за 30 дней июня:\n");
for (int i = 0; i < 30; i++) {
printf("День %d: ", i + 1);
scanf("%lf", &temp[i]);
sum += temp[i];
}
avg = sum / 30;
printf("\nСредняя температура: %.2f°C\n", avg);
printf("\nДни с отклонением >5°C от средней:\n");
for (int i = 0; i < 30; i++) {
double deviation = temp[i] - avg;
if (deviation > 5 || deviation < -5) {
printf("День %d: %.2f°C (отклонение: %+.2f°C)\n",
i + 1, temp[i], deviation);
}
}
return 0;
}
program JuneWeather;
var
temp: array[1..30] of real;
sum, avg, deviation: real;
i: integer;
begin
sum := 0;
writeln('Введите температуры за 30 дней июня:');
for i := 1 to 30 do
begin
write('День ', i, ': ');
readln(temp[i]);
sum := sum + temp[i];
end;
avg := sum / 30;
writeln;
writeln('Средняя температура: ', avg:0:2, '°C');
writeln;
writeln('Дни с отклонением >5°C от средней:');
for i := 1 to 30 do
begin
deviation := temp[i] - avg;
if (deviation > 5) or (deviation < -5) then
writeln('День ', i, ': ', temp[i]:0:2, '°C (отклонение: ', deviation:0:2, '°C)');
end;
end.
temp = [0.0] * 30
total = 0
print("Введите температуры за 30 дней июня:")
for i in range(30):
temp[i] = float(input(f"День {i + 1}: "))
total += temp[i]
avg = total / 30
print(f"\nСредняя температура: {avg:.2f}°C")
print("\nДни с отклонением >5°C от средней:")
for i in range(30):
deviation = temp[i] - avg
if deviation > 5 or deviation < -5:
print(f"День {i + 1}: {temp[i]:.2f}°C (отклонение: {deviation:+.2f}°C)")
🔐 Задача 2: Криптографическая головоломка Буратино
Условие: Шифр замка — двузначное число. Сумма цифр + произведение цифр = само число. Найти все варианты.
Математический подход: Пусть число 10a + b, где a и b — цифры.
Условие: (a + b) + (a * b) = 10a + b
Упрощаем: a + a*b = 10a → a*b = 9a → b = 9 (при a ≠ 0)
#include <stdio.h>
int main() {
printf("Возможные коды замка:\n");
for (int num = 10; num <= 99; num++) {
int a = num / 10; // первая цифра
int b = num % 10; // вторая цифра
if ((a + b) + (a * b) == num) {
printf("%d ", num);
}
}
printf("\n");
return 0;
}
program LockCodes;
var
num, a, b: integer;
begin
writeln('Возможные коды замка:');
for num := 10 to 99 do
begin
a := num div 10; { первая цифра }
b := num mod 10; { вторая цифра }
if (a + b) + (a * b) = num then
write(num, ' ');
end;
writeln;
end.
print("Возможные коды замка:")
for num in range(10, 100):
a = num // 10 # первая цифра
b = num % 10 # вторая цифра
if (a + b) + (a * b) == num:
print(num, end=" ")
print()
Результат: 19, 29, 39, 49, 59, 69, 79, 89, 99
Проверка для 19: (1+9) + (1×9) = 10 + 9 = 19 ✓
✨ Ключевые выводы
Подведём итоги изученного материала.
Массивы — фундамент структур данных. Понимание массивов критически важно для изучения списков, стеков, очередей, деревьев. Индексация с 0 в Си — не каприз, а соглашение. Это связано с тем, как адресуется память на низком уровне. Алгоритмическая сложность имеет значение. Разница между O(n) и O(n²) может означать часы вычислений на больших данных. Простые алгоритмы — основа сложных. Сортировка пузырьком неэффективна для миллионов элементов, но её принцип лежит в основе более продвинутых методов. Массивы везде: обработка изображений (массив пикселей), аудио (массив сэмплов), игры (массив игровых объектов), машинное обучение (тензоры — многомерные массивы).🤔 Проверь себя
Мини-кейсы для проверки понимания материала.
Мини-кейс 1: У тебя есть массив ID пользователей, вошедших в систему за последний час. Как быстро проверить, входил ли конкретный пользователь, если массив неотсортирован? Отсортирован?
Подумай о:
- Какой алгоритм поиска использовать в неотсортированном массиве?
- Можно ли ускорить поиск в отсортированном массиве?
- Какова будет сложность каждого подхода?
Мини-кейс 2: В игре персонажи хранятся в массиве. При смерти персонажа его нужно удалить. Какая операция более эффективна: сдвиг всех элементов или просто пометка ячейки как "пустая"?
Рассмотри:
- Сколько операций требует каждый подход?
- Как это повлияет на обход массива?
- Какие есть плюсы и минусы каждого метода?
Мини-кейс 3: Тебе нужно найти медиану (среднее значение при упорядочивании) массива из 1001 элемента. Какой первый шаг?
Подсказка:
- Что нужно сделать с массивом перед поиском медианы?
- На какой позиции будет находиться медиана после сортировки?
- Нужно ли полностью сортировать массив?
Задача: Напиши функцию, которая проверяет, является ли массив палиндромом (читается одинаково слева направо и справа налево).
Алгоритм:
- Сравнивай элементы с индексами i и n-1-i
- Достаточно проверить до середины массива
- Если хотя бы одна пара не совпадает — не палиндром
💻 Практические задания
Примени полученные знания на практике!
📝 Задание 1: Работа с температурами
Создай программу, которая:
- Вводит температуры за неделю
- Находит самую высокую и низкую температуру
- Вычисляет среднюю температуру
- Определяет, сколько дней было теплее/холоднее средней
🔢 Задание 2: Обработка чисел
Напиши программу, которая:
- Заполняет массив из 20 случайных чисел от 1 до 100
- Находит сумму чётных элементов
- Подсчитывает количество элементов, кратных 3
- Выводит элементы в обратном порядке
🎲 Задание 3: Анализ оценок
Разработай программу для анализа оценок класса:
- Ввод оценок 10 учеников (от 2 до 5)
- Подсчёт количества каждой оценки
- Нахождение средней оценки класса
- Определение количества отличников (5) и двоечников (2)
🔄 Задание 4: Циклический сдвиг
Реализуй программу циклического сдвига массива:
- Создай массив из 8 элементов
- Реализуй сдвиг всех элементов на 1 позицию вправо
- Последний элемент должен стать первым
- Например: {1,2,3,4,5} → {5,1,2,3,4}
Массивы — мышление в терминах коллекций данных
🚀 Отличная работа! Массивы — это не просто учебная тема. Это мышление в терминах коллекций данных, понимание того, как компьютер организует и обрабатывает информацию в памяти. Освоив массивы, ты делаешь шаг к пониманию алгоритмов, которые меняют мир — от поисковых систем до искусственного интеллекта.
Проверь себя
5 случайных вопросов по этому уроку — при следующем открытии будут другие. Ответы проверяются сразу, без регистрации.