데이터 · 10
리스트와 배열
여러 값을 한 줄로: 개수, 처음과 끝, 합, 모두 바꾸기.
리스트(배열)는 값 여러 개를 순서대로 담아요.
아래 예제는 수들을 읽어 개수, 처음과 끝, 합을 찍고 모두 두 배로 바꿔요.
n = int(input())nums = list(map(int, input().split()))print(len(nums))print(nums[0], nums[-1])print(sum(nums))doubled = [x * 2 for x in nums]print(*doubled)const [n, ...nums] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number);console.log(nums.length);console.log(nums[0], nums[nums.length - 1]);console.log(nums.reduce((a, b) => a + b, 0));const doubled = nums.map((x) => x * 2);console.log(doubled.join(" "));import { readFileSync } from "node:fs";const [n, ...nums]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number);console.log(nums.length);console.log(nums[0], nums[nums.length - 1]);console.log(nums.reduce((a, b) => a + b, 0));const doubled: number[] = nums.map((x) => x * 2);console.log(doubled.join(" "));import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) nums[i] = sc.nextInt(); System.out.println(nums.length); System.out.println(nums[0] + " " + nums[n - 1]); int sum = 0; for (int x : nums) sum += x; System.out.println(sum); StringBuilder doubled = new StringBuilder(); for (int i = 0; i < n; i++) doubled.append(i > 0 ? " " : "").append(nums[i] * 2); System.out.println(doubled); }}using System;using System.Linq; class Program{ static void Main() { int n = int.Parse(Console.ReadLine()); int[] nums = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); Console.WriteLine(nums.Length); Console.WriteLine($"{nums[0]} {nums[^1]}"); Console.WriteLine(nums.Sum()); int[] doubled = nums.Select(x => x * 2).ToArray(); Console.WriteLine(string.Join(" ", doubled)); }}#include <iostream>#include <numeric>#include <vector> int main() { int n; std::cin >> n; std::vector<int> nums(n); for (int& x : nums) std::cin >> x; std::cout << nums.size() << '\n'; std::cout << nums.front() << ' ' << nums.back() << '\n'; std::cout << std::accumulate(nums.begin(), nums.end(), 0) << '\n'; for (int i = 0; i < n; i++) std::cout << (i > 0 ? " " : "") << nums[i] * 2; std::cout << '\n';}#include <stdio.h> int main(void) { int n, nums[1000], sum = 0; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &nums[i]); printf("%d\n", n); printf("%d %d\n", nums[0], nums[n - 1]); for (int i = 0; i < n; i++) sum += nums[i]; printf("%d\n", sum); for (int i = 0; i < n; i++) printf(i > 0 ? " %d" : "%d", nums[i] * 2); printf("\n"); return 0;}n = 콘솔.줄읽기().수로변환();nums = 콘솔.수들읽기();콘솔.쓰기(nums.개수);콘솔.쓰기(nums[0] + " " + nums[nums.개수 - 1]);total = 0;doubled = [];각각 (x 에서 nums){ total += x; doubled.넣기(x * 2);}콘솔.쓰기(total);콘솔.쓰기(doubled);5 3 1 4 1 5
5 3 5 14 6 2 8 2 10
핵심
- 번호는 0부터예요.
그래서 마지막 값은개수 - 1번이에요. - 크기가 정해진 배열과, 값을 더 넣을 수 있는 목록 두 종류가 있어요.
이름과 쓰는 법은 언어마다 달라요. - 합·최댓값은 처음부터 끝까지 한 번 훑으며 구해요.
"모두 두 배" 같은 변환을 한 줄로 쓰는 언어도 있어요. b = a는 복사가 아니에요.
같은 목록에 이름을 하나 더 붙이는 거라서,b에 넣으면a도 바뀌어요(C++vector만 대입하면 복사돼요).- 범위를 벗어나 읽으면 대부분 오류로 멈춰요.
멈추지 않고 엉뚱한 값을 주는 언어가 더 위험해요.
언어별로 쓰는 법
| Python | list — append, len(nums), 마지막은 nums[-1].sum·max가 있고, 두 배는 [x * 2 for x in nums].범위 밖은 IndexError |
|---|---|
| JavaScript | 배열 — push, length, 마지막은 nums.at(-1).합은 reduce, 최댓값은 Math.max(...nums), 변환은 map.범위 밖은 오류 없이 undefined |
| TypeScript | JavaScript와 같아요.number[]처럼 담을 타입을 적어요 |
| Java | 고정 배열 int[] a = new int[n](a.length), 늘어나는 ArrayList<Integer>(add, size(), get(i)).합은 Arrays.stream(a).sum()이나 반복문.범위 밖은 ArrayIndexOutOfBoundsException |
| C# | 고정 int[](Length), 늘어나는 List<int>(Add, Count).마지막은 nums[^1].LINQ Sum()·Max()·Average()·Select.범위 밖은 IndexOutOfRangeException |
| C++ | std::vector<int> — push_back, size(), 마지막은 back().합은 std::accumulate, 최댓값은 std::max_element.[]는 범위를 확인하지 않고, at(i)는 예외를 던져요 |
| C | int a[1000]처럼 크기를 미리 정하고, 개수는 따로 들고 다녀요.합·최댓값·변환은 모두 반복문. 범위 밖을 읽어도 아무 말이 없어요 |
| Craykon | [ ] — 넣기, 개수(1만 개까지), 마지막은 nums[nums.개수 - 1].합·최댓값은 반복문. 범위 밖은 "목록에는 0~4번만 있어요" 오류 |
자주 하는 실수
최댓값을 0에서 시작했어요
nums = [-3, -1]
best = 0
for x in nums:
if x > best: best = x
print(best)→ 0 — 값이 모두 음수라 한 번도 바뀌지 않아요(답은 -1)
첫 값 nums[0]에서 시작해요.
범위 밖을 읽었는데 멈추지 않아요JavaScript · TypeScript · C · C++
const nums = [3, 1, 4];
console.log(nums[3]);
console.log(nums[-1]);→ undefined가 두 번 — 오류 없이 지나가요. C·C++ []는 옆 메모리의 아무 값이나 읽어요
읽기 전에 번호가 0부터 개수 - 1 안인지 확인해요.
평균이 정수로 잘렸어요Java · C# · C · C++
int sum = 14, n = 5;
double avg = sum / n;→ 2 — 14 / 5가 먼저 정수 나눗셈이 돼요(2.8이 아니에요)
나누기 전에 바꿔요: (double)sum / n → 2.8.
언어마다 다른 점
목록을 통째로 찍으면 언어마다 모양이 달라요: Python
빈칸으로 이어 찍으려면 Python
목록을 통째로 찍으면 언어마다 모양이 달라요: Python
[3, 1, 4], JavaScript [ 3, 1, 4 ], Java 배열은 [I@1b6d3586 같은 이름표, C# 배열은 System.Int32[].빈칸으로 이어 찍으려면 Python
print(*nums), JavaScript nums.join(" "), C# string.Join(" ", nums), Java는 반복문을 쓰고, 크레이콘 콘솔.쓰기(nums)는 바로 3 1 4로 찍어요.