본문 바로가기

 

배열의 개요

5명의 학생이 있는 한 학급에서 국어, 수학, 사회, 과학의 시험 점수를 프로그램으로 관리한다고 생각해보자. 학생 한 명당 4개의 값을 저장해야 하므로 20개의 변수가 필요하다.
만약 학생 수가 500명이라면 2,000개의 변수를 생성해서 관리해야 한다. 이렇게 프로그램을 작성하는 것은 번거로운 작업이 아닐 수 없다.
이런 경우에 배열을 사용하면 편한데, 배열을 사용하면 한 번에 많은 수의 변수를 생성할 수 있다. 배열은 동일한 특성을 가지며 일정한 규칙에 따라 몇몇 요소가 나열되어 있는 데이터 집합을 의미한다.
예를 들어, 5개의 값을 저장할 수 있는 배열 a의 구조를 도식화 하면 다음과 같다. 소괄호 안의 수를 첨자라 하는데 언어에 따라 0으로 시작되기도 하고 1로 시작되기도 한다. C 언어에서는 0으로 시작되므로 이 책에서 배열 첨자는 0으로 시작된다고 가정한다. a(0), a(1), a(2), a(3), a(4) 각각을 배열 요소라 한다.

a(3) 요소에 30을 저장하는 순서도 문장은 다음과 같다.


다음은 10, 20, 30을 요소로 하는 a 배열을 생성하는 C 문장이다.

a 배열의 구조는 다음과 같은데, a[0] 값은 10, a[1] 값은 20, a[2] 값은 30이 된다.

 

score라는 이름의 배열에 90, 100, 95를 하나씩 저장하고 score 배열 요소를 출력하는 순서도와 C 프로그램,score의 구조는 다음과 같다.

② 2차원 배열

앞에서 살펴본 배열에서는 첨자가 1개인데 이와 같이 첨자가 1개인 배열을 1차원 배열이라 한다. 첨자를 여러 개 사용하는 다차원 배열도 있는데 특히 첨자를 2개 사용하는 2차원 배열이 주로 사용된다.예를 들어, 2차원 배열 a(3, 2)는 3행 2열 배열을 말하는데 구조를 도식화 하면 다음과 같다.

a(2, 1) 요소에 30을 저장하는 문장은 다음과 같다.

다음은 2차원 배열을 생성하는 문장을 C언어로 나타낸 것이다.

이렇게 생성된 배열의 구조는 다음과 같은데, 1차원 배열에서와 마찬가지로 첨자가 0으로 시작되는 점을 주의해야 한다.

3행 2열 배열 s의 1행에 90, 95, 2행에 80, 85, 3행에 70, 75를 저장하고 출력하는 C 프로그램은 다음과 같다.


예제

 

예제38

1부터 10까지의 수 저장하고 출력하기

i가 1부터 1씩 증가하며 10이 될 때까지 반복하며 i 값을 배열 a(i-1)에 저장한다. 결국 a(0)에는 1, a(1)에는 2, a(2)에는 3, ..., a(9)에는 10이 저장된다.

#include <stdio.h>

int main()
{
	int i, a[10];
	for (i = 1; i <= 10; i++)
		a[i - 1] = i;
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	return 0;
}

예제39

10, 20, 30, ..., 100 저장하고 거꾸로 출력하기

i가 1부터 1씩 증가하며 10이 될 때까지 반복하며 i*10을 a(i-1)에 저장한다. 그리고 i가 9부터 1씩 감소하며 0이 될 때까지 반복하며 a(i) 값을 출력한다.

#include <stdio.h>
int main()
{
	int i, a[10];
	for (i = 1; i <= 10; i++)
		a[i - 1] = i * 10;
	for (i = 9; i >= 0; i--)
		printf("%d ", a[i]);
	return 0;
}

예제40

배열 요소 거꾸로 뒤집기

i가 0부터 1씩 증가하며 4가 될 때까지 반복하며 a(i)와 a(9-i)를 교환한다. 결국 a(0)과 a(9)가, a(1)과 a(8)이, a(2)와 a(7)이, a(3)과 a(6)이, a(4)와 a(5)가 교환된다. a 값과 b 값을 교환하는 절차는 다음과 같다.

#include <stdio.h>
int main()
{
	int i, a[10], temp;
	for (i = 0; i < 10; i++) {
		a[i] = i + 1;
	}
	for (i = 0; i < 5; i++) {
		temp = a[i];
		a[i] = a[9 - i];
		a[9 - i] = temp;
	}
	for (i = 0; i < 10; i++) {
		printf("%d ", a[i]);
	}
	return 0;
}

예제41

배열 a 요소 배열 b에 거꾸로 저장하기

배열 a 요소를 거꾸로 해서 배열 b에 저장한다.

i가 0부터 1씩 증가하며 9가 될 때까지 반복하며 a(9-i) 값을 b(i)에 저장한다. 결국 b(0)에는 a(9) 값이, b(1)에는 a(8) 값이, ..., b(9)에는 a(0) 값이 저장된다.

#include <stdio.h>
int main()
{
	int i, a[10], b[10];
	for (i = 0; i < 10; i++) {
		a[i] = i + 1;
	}
	for (i = 0; i < 10; i++) {
		b[i] = a[9 - i];
	}
	for (i <= 0; i < 10; i++) {
		printf("%d ", b[i]);
	}
	return 0;
}

예제42

배열 요소 왼쪽으로 한 칸씩 원형으로 이동하기

배열 요소를 왼쪽으로 한 칸씩 원형으로 이동하는 동작 전후 구조는 다음과 같다.

temp에 a(0) 값을 저장하고, i가 0부터 1씩 증가하며 8이 될 때까지 반복하며 a(i+1) 값을 a(i)에 저장한다. 그리고 temp 값을 a(9)에 저장한다.

#include <stdio.h>
int main()
{
	int i, a[10], temp;
	for (i = 0; i < 10; i++) {
		a[i] = i + 1;
	}
	temp = a[0];
	for (i = 0; i < 9; i++) {
		a[i] = a[i + 1];
	}
	a[9] = temp;
	for (i = 0; i < 10; i++) {
		printf("%d ", a[i]);
	}
	return 0;
}

예제43

배열 최댓값 구하기

a(0) 값을 max에 저장하고, i가 1부터 1씩 증가하며 9가 될 때까지 반복하며 a(i) 값이 max값보다 크면 a(i) 값을 max에 저장한다.

#include <stdio.h>
int main()
{
	int i, max, a[10] = { 10,70,100,30,50,20,60,80,90,40 };
	max = a[0];
	for (i = 1; i <= 9; i++) {
		if (max < a[i])
			max = a[i];
	}
	printf("최댓값: %d", max);
	return 0;
}

예제44

에라토스테네스의 체

그리스의 수학자이자 지리학자인 에라토스테네스가 고안한 소수를 찾는 방법이다.

 

이 방법으로 소수를 찾으려면 2부터 시작해 자연수를 차례로 쓴 다음,

2 이외의 2의 배수,

3 이외의 3의 배수,

5 이외의 5의 배수의 순서로 수를 지워나가면, 끝에 남는 수가 소수이다.

그러면 체로 친 것처럼 끝에 남는 수가 있다.

 

자신과 1 이외의 다른 수로 는 나누어떨어지지 않는 소수이고, 위와 같이 소수를 찾는 방법을 에라토스테네스의 체라고
한다. 에라토스테네스의 체를 이용해서 2부터 20까지의 소수를 찾는 예를 살펴보자.

1부터 100까지의 소수를 위 방법으로 구현하라.

#include <stdio.h>
int main()
{
	int a[101] = { 0 }, i, j;
	for (i = 2; i <= 100; i++) {
		if (a[i] == 0) {
			for (j = i * 2; j <= 100; j = j + i) {
				a[j] = 1;
			}
		}
	}
	for (i = 2; i <= 100; i++) {
		if (a[i] == 0)
			printf("%d ", i);
	}
	return 0;
}

예제45

10진수를 2진수로 변환하여 리스트에 저장하기

(문제를 못 풀더라도, 2진수 개념은 알아둡시다.)

10진수를 2진수로 변환하는 과정을 이해하려면 진법의 개념을 먼저 이해해야 한다.

진법이란 사용할 수 있는 숫자의 개수와 위치 값을 정의해주는 수 체계이다.

한 자리에 사용할 수 있는 숫자의 개수는 해당 진법과 같으며, 사용할 수 있는 숫자는 0에서 시작해서 해당 진법의 수보다 1적은 수까지 가능하다.

그러므로 10진법에서 사용할 수 있는 숫자는 0, 1, 2, …, 8, 9로 10개가 되고, 2진법에서는 0과 1로 2개를 사용할 수 있다.


16진법과 같이 10진법보다 큰 진법의 경우에는 0부터 9까지의 수 외에도 다른 수가 더 필요한데 이런 경우에 A, B, C, D, E, F를 사용한다. 16진법의 A는 10진수 10을, B는 10진수 11을, …, F는 10진수 15를 의미한다.

 

컴퓨터에서 많이 사용되는 10진수, 2진수, 8진수 16진수의 관계를 표로 나타내면 다음과같다.

10진수 2진수 8진수 16진수
0 0 0 0
1 1 1 1
2 10 2 2
3 11 3 3
4 100 4 4
5 101 5 5
6 110 6 6
7 111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F
16 10000 20 10

 

다음으로 진수 변환을 알아보자. 먼저 10진수를 2진수 또는 8진수로 변환하는 내용에 대해 살펴보자.
10진수를 다른 진수로 변환하려면 10진수를 변환하고자 하는 진수로 몫이 0이 될 때까지계속해서 나누고 나머지를 역순으로 나열한 값이 변환한 값이 된다.


예를 들어 37을 2진수로 변환하려면 다음과 같이 37을 2로 계속해서 나눈다. 그리고 나머지를 역순으로 배열하면 100101이 되는데 이 값이 10진수 37을 2진수로 변환한 값이 된다.

 

또 다른 예로 10진수를 8진수로 변환하는 과정은 다음과 같다. 10진수 87을 8진수로 변환
하면 127이다.

10진수를 2진수로 변환하려면 10진수를 2로 나누어 나머지를 구하고, 몫을 2로 다시 나누어 나머지를 구하는 동작을 반복한다. 몫이 0이 되면 반복을 중단하고, 구한 나머지를 역순으로 나열한 값이 결과 값이 된다.

 

10진수를 입력받아, 2진수로 출력하는 프로그램을 개발하세요.

 

 

 

예제 46

배열에 저장된 2진수를 10진수로 변환하기

2진수를 10진수로 변환하는 내용에 대해 살펴보자.
수 체계에 있어서 중요한 개념 중 하나는 자리 값인데, 모든 수의 각 숫자는 자리 값을가지고 있다.

각 숫자의 자리 값은 그 위치가 의미하는 제곱수를 해당 진법에 적용하면되는데, 각 위치가 의미하는 제곱수는 가장 오른쪽이 0이고 왼쪽으로 가면서 1을 더한 값이 된다.


예를 들면, 2진수 11001은 다음과 같은 절차를 거쳐 10진수 25가 된다.

이와 같이 2진수를 10진수로 변환할 때는 2진수 각 자리를 10진수로 변환하여 모두 더하면 된다. 

단, 2진수는 5자리라 가정한다.

 

2진수를 한자리  10진수를 출력하는 프로그램을 만드세요.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

과제

 

과제48

10부터 1까지의 수를 배열에 저장하고 출력하는 순서도와 C 프로그램을 작성하여라.

 

과제49

60, 70, 80, 90, 100을 배열에 저장하고 거꾸로 출력하는 순서도와 C프로그램을 작성하여라.

 

과제50

배열 요소를 오른쪽으로 한 칸씩 원형으로 이동하는 순서도와 C 프로그램을 작성하여라.

 

과제51

임의의 10개의 수를 저장하고 있는 배열에서 최솟값을 구하는 순서도와 C 프로그램을 작성하여라.

 

 

 

 

 

 

 

 

 


이후는 선택 문제 입니다.

코드만 구현하는 이유는, 한번쯤 공부하면서 명칭을 기억만 해도 좋겠다는 의도입니다.

 

연습문제

예제47

선형 탐색 알고리즘

탐색이란 컴퓨터에 저장된 데이터 집합에서 어떤 조건이나 성질을 만족하는 데이터를 찾는것이다.


탐색하고자 하는 데이터는 무작위로 섞여있는 데이터와 특정한 규칙에 따라 정렬된 데이터로 구분할 수 있다. 데이터의 유형에 따라 적합한 탐색 방법이 있는데, 우선 무작위로 섞여있는 데이터를 탐색하는 방법인 선형 탐색에 대해 살펴보자.


선형 탐색은 순차 탐색이라고도 하는데, 주어진 데이터 집합에서 원하는 데이터를 처음부터 순차적으로 비교하면서 찾는 방법이다.


다음 데이터 집합에서 선형 탐색을 이용해서 데이터 7을 탐색하는 과정을 알아보자.

① 첫 번째 데이터인 15와 7을 비교한다. 값이 다르므로 다음으로 이동한다.

② 두 번째 데이터인 19와 7을 비교하는데, 다르므로 다음으로 이동한다.

③ 세 번째 데이터인 5와 7을 비교하는데, 다르므로 다음으로 이동한다.

④ 네 번째 데이터인 7과 찾고자 하는 3이 같으므로 원하는 데이터를 찾고 탐색을 종료한다.

만약 마지막까지 찾는 데이터가 없으면 탐색 실패를 알려주고 끝내야 한다.

 


 

임의의 숫자를 10개를 요소로 가지는 리스트를 만들고, 키 값을 입력했을 때 인덱스를 찾아 출력하는 선형 탐색 알고리즘을 구현하라.

 

#실행결과

# 키: 11
# 6 에서 탐색 성공 (a = [26, 27, 39, 63, 57, 75, 11, 76, 80, 18] 리스트 일 때)

 

# 순서도 참고

# 로직 참고

더보기

01 cnt가 10보다 작은 동안 비교 작업을 반복해서 실행한다.
02 key와 a[cnt]가 같으면 “탐색 성공”을 출력하고 break에 의해 반복 구조를 빠져나온다.
03 cnt가 10과 같으면 “탐색 실패”를 출력한다.

 

# 참고 (알아만 두세요, 위처럼 직접 만들 수 있어야 합니다.)

in과 index를 이용해서 리스트에서 탐색을 할 수 있다. key in a는 리스트a에 key가 있는지 확인하는 것이고, a.index(key)는 리스트 a에서 key의 위치를 의미한다.

 

 

예제47

이진 탐색 알고리즘

이진 탐색은 정렬된 데이터 집합을 이분화하면서 탐색하는 방법이다.
다음 데이터 집합에서 이진 탐색을 이용해서 데이터 9를 탐색하는 과정을 알아보자.


 

임의의 숫자를 10개를 요소로 가지는 리스트를 만들고, 키 값을 입력했을 때 인덱스를 찾아 출력하는 이진 탐색 알고리즘을 구현하라.

 

#실행결과

# 키: 39
# 4 에서 탐색 성공 (a = [11, 18, 26, 27, 39, 57, 63, 75, 76, 80] 리스트 일 때)

 

# 순서도 참고

# 로직 참고

더보기

01 low 값이 high보다 작거나 같은 동안 비교 작업을 반복해서 실행한다.
02 low와 high 값의 평균을 mid에 저장한다.
03 key와 a[mid]가 같으면 “탐색 성공”을 출력하고, 반복 구조를 빠져나온다.
04 key가 a[mid]보다 작으면 high변수에 mid-1을 저장한다.
05 key가 a[mid]보다 크면 low변수에 mid+1을 저장한다.
06 low 값이 high 값보다 크면 “탐색 실패”를 출력한다.

 

 

예제48

선택 정렬 알고리즘

 

순서에 상관없이 배열된 데이터를 일정 규칙에 따라 배열하는 것을 정렬이라 하는데, 엑셀은 물론이고 글을 비롯한 많은 소프트웨어에 정렬 기능이 있다.


정렬을 하는 방법은 여러 가지가 있는데, 그 중 선택 정렬에 대해 살펴보자.

 

선택 정렬은 정렬되지 않은 데이터들에 대해 가장 작은 데이터를 찾아 가장 앞의 데이터와교환해가는 방식이다. 

그러면 선택 정렬의 동작 과정을 다음 데이터를 이용해서 살펴보자.

 


임의의 리스트에 요소를 원하는 만큼 무작위로 넣고, 선택 정렬 알고리즘을 구현하여 정렬하라

 

# 실행결과

# [10, 20, 30, 40, 50, 60]  (a =[20, 50, 30, 10, 60, 40] 리스트 일 때)

 

 

# 순서도 참고

# 로직 참고

더보기

01 i 값이 0부터 1씩 증가하며 4가 될 때까지 반복해서 실행한다.
02 j 값이 i+1부터 1씩 증가하며 5가 될 때까지 교환 작업을 반복해서 실행한다.
03 a[j]가 a[m]보다 작으면 m에 j 값을 저장한다.
04 a[j]와 a[m]을 교환한다.

 

# 내장 함수 참고 (알아만 두세요, 함수를 배우면 내장함수를 만들 수 있어야 합니다.)

#sort 함수를 이용해서 리스트 요소를 정렬할 수 있다.

#a = [20, 50, 30, 10, 60, 40]
#a.sort()
#print(a)

 

 

예제49

버블 정렬 알고리즘

버블 정렬은 서로 이웃한 데이터들을 비교하며 가장 큰 데이터를 가장 뒤로 보내며 정렬하는 방식이다.

 


임의의 리스트에 요소를 원하는 만큼 무작위로 넣고, 버블 정렬 알고리즘을 구현하여 정렬하라

 

# 실행결과

# [10, 20, 30, 40, 50, 60]  (a =[20, 50, 30, 10, 60, 40] 리스트 일 때)

 

# 순서도 참고

 

# 로직 참고

더보기

01 i 값이 0부터 1씩 증가하며 4가 될 때까지 반복해서 실행한다.
02 j 값이 0부터 1씩 증가하며 5-i-1이 될 때까지 교환을 반복해서 실행한다.
03 a[j]가 a[j+1]보다 크면 a[j]와 a[j+1]을 교환한다.

 

 

예제50

병합 정렬 알고리즘


임의의 리스트 2개에 요소를 원하는 만큼 무작위로 넣고, 병 정렬 알고리즘을 구현하여 정렬하라

 

 

# 실행결과

# [1, 3, 3, 4, 5, 7, 8, 10] (a = [1, 3, 5, 7], b = [3, 4, 8, 10])

 

 

# 순서도 참고

# 소스코드, 로직 

더보기
a = [1, 3, 5, 7]
b = [3, 4, 8, 10]
c = []
i = 0
j = 0
while i<4 and j<4:
	if a[i]<b[j]:
		c.append(a[i])
		i = i+1
	else:
		c.append(b[j])
		j = j+1
if i==4:
	while j<4:
		c.append(b[j])
		j = j+1
	else:
		while i<4:
			c.append(a[i])
			i = i+1
print(c)


# 로직 참고

01 i가 4미만이고 j가 4미만인 동안 반복해서 실행한다.
02 a[i]가 b[j]보다 작으면 c에 a[i]를 추가하고 i 값을 1증가시킨다. 그렇지 않으면 c에 b[j]를 추가하고 j 값을 1증가시킨다.
03 i가 4이면 14~16을 실행하고, 그렇지 않으면 18~20을 실행한다.
04 j가 4보다 작은 동안 c에 b[j]를 추가하고 j 값을 1증가시킨다.
05 i가 4보다 작은 동안 c에 a[i]를 추가하고 i 값을 1증가시킨다.

 

 

 

 

 

과제

과제 33

내림차순으로 정렬된 데이터 집합에 대한 이진 탐색을 하는 순서도와 파이썬 프로그램을 작성하여라.

 

과제 34

삽입 정렬은 다음과 같이 이미 정렬된 부분에서 자신의 위치를 찾아 삽입하며 정렬하는 방식이다. 삽입 정렬을 이용해서 정렬하는 순서도와 파이썬 프로그램을 작성하여라

# 순서도, 소스코드

더보기
a = [3, 7, 2, 8, 5, 1, 10, 9, 4, 6]

for i in range(1, 10):
	key = a[i]
	j = i-1
	while j>=0:
		if key<a[j]:
			a[j+1] = a[j]
		else:
			break
		j = j-1
	a[j+1] = key
print(a)

 

 

 

 

BasicLike

어? 나 프로그래밍 좋아하네?