Массивы (одномерные)

Во многих задачах нужно хранить не одно число, а целую последовательность:
оценки ученика, результаты замеров, элементы ряда, высоты столбиков на диаграмме.

Держать десятки отдельных переменных неудобно.

Для этого в Java есть массивы.

Массив — это набор однотипных значений под одним именем, к каждому элементу обращаемся по номеру (индексу).

int[] a = new int[5];  // массив из 5 целых чисел: a[0], a[1], ..., a[4]

Основное

Одномерный массив целых чисел:

int[] a = new int[n];      // создать массив длины n
a[i] = 10;                 // записать значение в ячейку с индексом i
int x = a[i];              // прочитать значение из ячейки
int len = a.length;        // длина массива

Важно:

  • индексы идут от 0 до a.length - 1;
  • при выходе за границы (a[-1], a[n]) будет ошибка во время работы программы;
  • все элементы нового int[] по умолчанию равны 0.

Идея массива

Без массива:

int x1, x2, x3, x4, x5;
// неудобно и легко запутаться

С массивом:

int[] a = new int[5];  // 5 целых чисел

Теперь можно обращаться к элементам по индексу:

a[0] = 10;
a[1] = 20;
a[2] = 30;

Объявление и создание массива

Общий шаблон:

тип[] имя = new тип[длина];

Примеры:

int n = 10;
int[] a = new int[n];       // массив целых чисел

double[] x = new double[5]; // массив из 5 дробных чисел

boolean[] used = new boolean[100]; // массив логических значений

Сначала указываем тип элементов и [], затем имя массива, затем создаём массив нужной длины через new.


Чтение массива из ввода

Частый случай: сначала во входе дано число n — сколько элементов, а затем n чисел.

import java.util.Scanner;

public class ReadArrayExample {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int n = in.nextInt();      // количество элементов
        int[] a = new int[n];      // создаём массив

        for (int i = 0; i < n; i++) {
            a[i] = in.nextInt();   // читаем i-й элемент
        }

        // вывод массива
        for (int i = 0; i < n; i++) {
            System.out.println(a[i]);
        }
    }
}

Важный момент: цикл по индексу почти всегда идёт от 0 до n - 1.


Примеры и типичные шаблоны

Сумма элементов массива

int n = in.nextInt();
int[] a = new int[n];

for (int i = 0; i < n; i++) {
    a[i] = in.nextInt();
}

int sum = 0;
for (int i = 0; i < n; i++) {
    sum = sum + a[i];   // или sum += a[i];
}

System.out.println(sum);

Минимум и максимум в массиве

int n = in.nextInt();
int[] a = new int[n];

for (int i = 0; i < n; i++) {
    a[i] = in.nextInt();
}

int min = a[0];
int max = a[0];

for (int i = 1; i < n; i++) {
    if (a[i] < min) {
        min = a[i];
    }
    if (a[i] > max) {
        max = a[i];
    }
}

System.out.println("min = " + min);
System.out.println("max = " + max);

Подсчёт количества элементов по условию

int n = in.nextInt();
int[] a = new int[n];

for (int i = 0; i < n; i++) {
    a[i] = in.nextInt();
}

int countPositive = 0;

for (int i = 0; i < n; i++) {
    if (a[i] > 0) {
        countPositive++;
    }
}

System.out.println(countPositive);

Поиск элемента в массиве

int n = in.nextInt();
int[] a = new int[n];

for (int i = 0; i < n; i++) {
    a[i] = in.nextInt();
}

int key = in.nextInt();   // кого ищем
boolean found = false;

for (int i = 0; i < n; i++) {
    if (a[i] == key) {
        found = true;
        break;
    }
}

if (found) {
    System.out.println("YES");
} else {
    System.out.println("NO");
}

Что нужно запомнить

Одномерный массив — это набор значений одного типа, доступ к каждому по индексу:

int[] a = new int[n];

Индексы идут от 0 до a.length - 1, выход за границы массива приводит к ошибке.

Типичные шаблоны работы с массивом: чтение в цикле, проход по всем элементам, вычисление суммы, минимума/максимума, подсчёт количества элементов по условию.

В C++ чаще всего используют std::vector — динамический массив.

#include <vector>

int n = 5;
std::vector<int> a(n); // n целых чисел: a[0], a[1], ..., a[n-1]

Основное

std::vector<int> a(n);   // создать массив длины n
a[i] = 10;               // записать значение в ячейку i
int x = a[i];            // прочитать значение
int len = (int)a.size(); // длина массива

Важно:

  • индексы идут от 0 до a.size() - 1;
  • при выходе за границы через a[i] поведение не определено (может «сломаться» как угодно);
  • у std::vector<int> a(n); все элементы по умолчанию равны 0.

Если нужна проверка границ, есть a.at(i) — он выбрасывает исключение при ошибке, но в задачах обычно используют a[i].


Чтение массива из ввода

Частый случай: сначала дано n, затем n чисел.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n;
    cin >> n;

    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    for (int i = 0; i < n; i++) {
        cout << a[i] << "\n";
    }

    return 0;
}

В Python чаще всего используют список list.

n = 5
a = [0] * n   # n целых чисел: a[0], a[1], ..., a[n-1]

Основное

a = [0] * n   # создать массив длины n
a[i] = 10     # записать значение в ячейку i
x = a[i]      # прочитать значение
length = len(a)

Важно:

  • индексы идут от 0 до len(a) - 1;
  • при выходе за границы будет ошибка IndexError.

Чтение массива из ввода

Частый случай: сначала n, затем n чисел.

n = int(input())
a = list(map(int, input().split()))

for x in a:
    print(x)

Если числа могут прийти не в одной строке, проще читать все сразу:

import sys

data = list(map(int, sys.stdin.read().split()))
n = data[0]
a = data[1:1+n]

for x in a:
    print(x)

В Java массив — это отдельный тип (int[]), длина задаётся при создании и дальше не меняется. Длина берётся через a.length, выход за границы даёт ошибку во время работы.

В C++ для задач обычно используют std::vector. Его размер можно менять, длина берётся через a.size(). При выходе за границы через a[i] нет гарантированной ошибки: программа может работать неправильно или упасть позже.

В Python список list по смыслу ближе к vector: размер можно менять. Длина через len(a), выход за границы сразу даёт IndexError.

По умолчанию новые элементы равны нулю: Java new int[n], C++ vector<int> a(n), Python [0] * n.

Для чтения ввода обычно используют: Java — цикл и Scanner.nextInt(), C++ — цикл и cin >> a[i], Python — split() + map(int, ...) или чтение всего ввода через sys.stdin.read().