1 / 73

CHAPTER 07. 배열

CHAPTER 07. 배열. 배열의 필요성과 편리성을 공부한다 . 1 차원 , 2 차원 , 다차원 배열의 선언과 사용법을 공부한다 . char 형 배열을 이용한 문자열 처리를 공부한다 . 배열을 이용한 다양한 프로그래밍을 공부한다 . 배열의 평균 , 최솟값 , 정렬하기 2 차원 행렬의 덧셈. 7.0 개요 p. 254. 배열 (array ). 7.1 1 차원 배열 p.255. 배열이란

taariq
Download Presentation

CHAPTER 07. 배열

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CHAPTER 07. 배열 배열의 필요성과 편리성을 공부한다. 1차원, 2차원, 다차원 배열의 선언과 사용법을 공부한다. char형 배열을 이용한 문자열 처리를 공부한다. 배열을 이용한 다양한 프로그래밍을 공부한다. 배열의 평균, 최솟값, 정렬하기 2차원 행렬의 덧셈

  2. 7.0 개요 p. 254 • 배열(array)

  3. 7.1 1차원 배열 p.255 • 배열이란 • 자료형이 같은 값 여러 개를 연속된 기억장소에 같은 이름(배열명)으로 저장한 것 즉 같은 자료형의 여러 변수들을 연속적으로 모아 둔 것 • 배열의 원소(element) • 배열의 차원

  4. 1차원 배열의 선언 p.255 • 예) • int age[1000];// 1000명의 나이 저장 배열 • double average[100]; // 100명의 평균을 저장하기 위한 배열 • char name[10]; // 10개의 문자를 저장하기 위한 배열 • 『주』 배열 원소수 • 정수형 상수만 가능 → 매크로 상수(6장 내용)는 가능 • 변수는 불가능

  5. 1차원 배열의 선언과 초기화 p.256 • 예) • int quiz[5] = {8, 9, 10, 8, 7}; • int sum[100] = {0}; • int error[ ] = {0, 1, 0, 2, 3, 0, 1};

  6. 1차원 배열 원소 참조 p.256 • 예) int quiz[5] = {8, 9, 10, 8, 7}; • quiz[0] = 1; • printf("%d", quiz[1]); • scanf("%d", &quiz[0]); • quiz[4]++;

  7. 1차원 배열 원소 참조 p.257 • 『주』범위를 초과한 첨자를사용하면? int a[3] = {21, 25, 20}; printf(“%d”, a[3]);  에러는 발생하지 않으나 a[3]은 a 배열에 포함된 기억장소가 아니므로 프로그램 실행 결과를 예측할 수 없게 됨

  8. 7.1.2 1차원 배열과 반복문 p.257 • 배열의 편리성 배열 원소수와 상관없이 반복문을 이용해 편리하게 코드화할 수 있다. printf("%3d ", quiz[0]); printf("%3d ", quiz[1]); printf("%3d ", quiz[2]); printf("%3d ", quiz[3]); printf("%3d ", quiz[4]); for (i=0; i< 5 ; i++) printf("%3d ", quiz[ i ]); 배열 원소수를 활용

  9. 7.2.1 5명 퀴즈 점수의 평균 및 평균 미만 학생 수 구하기 p.258 • 문제 입력: 5명의 퀴즈 점수 출력: 평균, 평균 미만 학생 수, 각 학생의 평균 점수와의 차이 • 퀴즈 점수 5개를 1차원 배열 quiz에 입력하기 (for문) • 평균 avg구하기 • sum ← quiz[0] + quiz[1] +quiz[2] +quiz[3] +quiz[4] (for문) • avg← sum / 5 • 평균 미만 수 count 구하기 (for문) • 각 학생에 대해 (avg >quiz[i])일때마다 count를 1 증가 • 각 학생에 대해 차이점수 (quiz[i] - avg)출력하기 (for문)

  10. 7-1 5명의 퀴즈 점수로부터 평균 및 평균 미만자 수 구하기 p.259 1 #include <stdio.h> 2 #define SIZE 5 // 원소수를 매크로 상수로 정의 3 4 int main() 5 { 6 int quiz[SIZE]; // 배열 선언 7 inti, count, sum; 8 double avg; 10 // 배열의 입력 11 printf("%d명의 점수를 순서대로 입력하세요.\n\n", SIZE); 12 for (i=0; i<SIZE; i++) 13 { 14 printf("%d번의 퀴즈 점수는? ", i+1); 15 scanf("%d", &quiz[i]); 16 }

  11. 7-1 5명의 퀴즈 점수로부터 평균 및 평균 미만자 수 구하기 p.259 18 // 배열 평균 sum ← quiz[0] + quiz[1] + quiz[2] + quiz[3] + quiz[4] 19 sum = 0; 20 for (i=0; i<SIZE; i++) 21 sum = sum + quiz[i]; 22 23 avg = (double)sum / SIZE; 24 25 // 평균 미만자 수 count 구하기 26 count = 0; 27 for (i=0; i<SIZE; i++) 28 if (quiz[i] < avg) 29 count++; Q) 19~29행을 하나의 for문으로 작성할 수 있을까? T) 배열처리 → 무조건 반복문 사용

  12. 7-1 5명의 퀴즈 점수로부터 평균 및 평균 미만자 수 구하기 p.259 31 // 결과 출력 32 printf("============================\n"); 33 printf(" 번호 점수 평균과의 차이 \n"); 34 printf("============================\n"); 35 for (i=0; i<SIZE; i++) 36 printf(" %2d %2d %5.1lf\n", i+1, quiz[i], quiz[i] - avg); 37 printf("============================\n"); 38 printf("평균 : %.1lf점 \n", avg); 39 printf("============================\n"); 40 printf("평균 미만 : %d명 \n", count); 41 42 return 0; 43 }

  13. 7.2.2 배열의 최솟값 구하기 p.261 • 문제: 배열의 최솟값 구하기 다섯 물질의 어는 점 5개 중 가장 낮은 어는 점 구하기 min의변화 3 • 해결과정 • min = 배열의 첫 원소; • 나머지 원소와 min을 비교해 더 작은 값을 min으로 저장하기 (for문) • if (min > 배열 원소) • min = 배열 원소;

  14. 7-2 배열의 최솟값 구하기 p.262 2 #define N 5 3 4 int main() 5 { 6 int f[N] = {3, 0, -30, -20, -1}; // 배열 선언 7 inti, min; 8 9 // 최솟값 구하기 10 min = f[0]; 11 for (i=1; i<N; i++) 12 { 13 if (f[i] < min) 14 min = f[i]; 15 } 16 18 printf("어는 점 목록:"); 19 for (i=0; i<N; i++) 20 printf("%4d", f[i]); 21 23 printf("\n가장 낮은 어는 점: %d \n", min);

  15. 7-2 배열의 최솟값 구하기 p.262 4 int main() 5 { 6 int f[N] = {3, 0, -30, -20, -1}; // 배열 선언 7 inti, min; 8 9 // 최솟값 구하기 10 min = f[0]; 11 for (i=0; i<N-1; i++) 12 { 13 if (f[i] < f[i+1]) 14 min = f[i]; 15 } 16 18 printf("어는 점 목록:"); 19 for (i=0; i<N; i++) 20 printf("%4d", f[i]); 21 23 printf("\n가장 낮은 어는 점: %d \n", min); • Q) 이코드의문제점은? • Hint) 최종 min에는 둘 중 한 개의 값이 저장됨

  16. 배열의 최솟값의 첨자도 구하기 『참고』 ※ 최솟값이 배열의 어느 원소인지도 출력하기 최솟값에해당하는 원소의 첨자를 저장하는 변수 index를 사용 23 printf("\n가장 낮은 어는 점: f[%d] = %d \n", index, f[index]); 실행결과 어는 점 목록: 3 0 -30 -20 -1 가장 낮은 어는 점: f[2] = -30

  17. 7.2.3 설문 조사 결과 구하기 p.263 • 문제 • 자료 • 응답자 30명의 연예인 5명에 대한 선호도 결과가 저장된 배열 • int survey[30] = {1, 3, 2, 5, 3, 2, 1, …, 1, 4, 2, 3}; • 출력 • 각 연예인 별 총 득표수가 저장된 배열 • intvote[6] = {0};

  18. 7.2.3 설문 조사 결과 구하기 p.263 • 해당 연예인의 득표수 누적 설문 조사 응답이 3 →vote[ 3 ]++ • 모든 응답마다 확인하여 연예인 득표수 누적하기 for (i=0; i<PERSONS; i++) vote[ survey[i] ]++ survey[i]

  19. 프로그램 7-3 설문 조사 결과 구하기 p.264

  20. 프로그램 7-3 설문 조사 결과 구하기 p.264

  21. [실습] 석차 구하기 /1 • 나의 석차 나보다 점수가 높은 사람의 수 + 1 • 초기화 • int kor[N] = {90, 80, 70, 60, 100}; • int math[N] = {81, 91, 81, 81, 100}; • int order[N]; • double avg[N]; • 알고리즘 • 모든 i에 대해 kor[i], math[i]를 이용하여 ave[i]를 구함 (for문) • 모든 i에 대해 배열 avg의 값으로 석차 order[i]를 구함(중첩 for문) • 모든 i에 대해 kor[i], math[i], ave[i], order[i]를 출력 (for문) ======================== 국어 수학 평균 석차 ======================== 90 81 85.50 2 80 91 85.50 2 70 81 75.50 4 60 81 70.50 5 100 100 100.00 1 kor[0] math[0] avg[0] order[0] → 첨자가같으면 같은 학생의 정보

  22. [실습] 석차 구하기/2 • 분석 • 학생 i의 평균: avg[i] = (double) (kor[i]+math[i]) / 2; • 첨자가 i인 학생의 석차 order[i] • 나의 석차 order[i]를 1로 초기화 • 초기치를 1로 주면 나중에 +1을 하지 않아도 됨 • 만일 0으로 초기화했다면 2. 과정 후 +1을 해야 최종 석차가 됨 • 내 평균(avg[i])과 모든 학생의 평균(avg[u], u=0~N-1)을 차례로 비교 (for문) • if(내평균 avg[i] < 다른평균 avg[u]) → 내석차 order[i]를 1증가  1. 2. 과정을 모든 학생에 대해(i=0~N-1) 반복하여 모든 학생의 석차 구하기 for (i=0; i<N; i++) { order[i] 구하기 } 1. 2. 과정

  23. 7.2.4 버블 정렬(오름차순) p.264 • 정렬(sort) • 프로그램에서가장 많이 처리하는 기능 중 하나 • 도서명을 가나다순으로 정렬하기 • 도서를 최근 출판년도 순으로 정렬하기 • 수능 성적을 내림차순으로 정렬하기 • 주소록의 이름을 가나다순으로 정렬하기 등 • 원소수 증가 시 실행 시간이 급격히 증가(원소수의 제곱에 비례)하는 문제 발생 → 실행 시간을 줄이기 위해 많은 정렬 알고리즘이 개발되었다.→ 그 중 하나가 빠른 ‘퀵 정렬’ → 알고리즘 자체가 쉽지 않다.→ 가장 단순한 버블 정렬알고리즘으로 정렬 프로그래밍 개념 소개

  24. 7.2.4 버블 정렬(오름차순) p.264 • 정렬 목표 • 버블 정렬(bubblesort)의 기본 원리 이웃 두 원소씩 차례대로 정렬하는 작업을 반복 → 배열 전체를 정렬 이 과정을 [그림 7-7]과 같이(배열 원소수-1)만큼 반복  정렬 완료

  25. 7.2.4 버블 정렬 p.266 • [그림 7-6] 과정을 (배열 원소수-1)만큼 반복  정렬 완료

  26. 7.2.4 버블 정렬: 두 변수의 값 교환 p.266 • 두 변수의 값을 교환하기: 잘못된 예 p.266 • 프로그램은 한 문장씩 차례로 실행되므로 뜻하지 않은 결과가 발생 • 두 변수의 값을 교환하기: 바른 방법 p.267 x의 값을 수정하기 전에 원본 값을 임시 저장소(temp)에 보관 1 x = 3, y = 1; 2 x = y; 3 y = x; 4 printf("x=%d, y=%d", x, y); • 2행에서 x의 값이 1로 수정되었으므로 1이 새로 저장 • x와 y 둘 다 y의 값이 저장 1 x = 3, y = 1; 2 temp = x; 3 x = y; 4 y = temp;

  27. 7-4 가장 단순한 버블 정렬 p.267 2 #define SIZE 5 3 4 int main() 5 { 6 inti, repeat, temp, a[SIZE] = {5, 4, 3, 2, 1}; 7 9 for (repeat=1; repeat<SIZE; repeat++) //(배열 원소수-1)번 반복 10 { 11 // 두 원소간 정렬을 차례대로 반복하기 12 for (i=0; i<SIZE-1; i++) 13 { 15 if (a[i] > a[i+1]) 16 { 17 temp = a[i]; 18 a[i] = a[i+1]; 19 a[i+1] = temp; 20 } 21 } 22 } // 바깥 for 끝

  28. 버블 정렬: [프로그램7-4]의 개선 p.268 [프로그램 7-4]의 문제점 12행의 for문은 이전 반복에서 정렬이 완료된 원소도 무조건 비교함 → 대략 전체 비교 회수의 반에 해당 → 불필요한 비교를 제거 → 실행 속도를 개선

  29. 버블 정렬: [프로그램7-4]의 개선 p.268 repeat가 1 → (a[0],a[1]), (a[1],a[2]), (a[2],a[3]), (a[3],a[4]) repeat가 2 → (a[0],a[1]), (a[1],a[2]), (a[2],a[3]) repeat가 3 → (a[0],a[1]), (a[1],a[2]) repeat가 4→ (a[0],a[1]) repeat가 1 →i가 0 ~ 3까지 a[i]와 a[i+1]비교 repeat가 2 →i가 0 ~ 2까지 “ repeat가 3 → i가 0 ~ 1까지 “ repeat가 4 → i가 0 ~ 0까지 “ • 14 for (repeat=1; repeat<SIZE; repeat++) • 15 { • 16 for (i=0; i<SIZE-repeat; i++) • 17 { • 18 if (a[i] > a[i+1]) • :

  30. 7-5 정렬이 완료된 원소 간 비교를 제거 p.269 2 #define SIZE 5 3 4 int main() 5 { 6 int i, repeat, temp, a[SIZE] = {5, 4, 3, 2, 1}; 7 13 // 버블 정렬 시작 14 for (repeat=1; repeat<SIZE; repeat++) 15 { 16 for (i=0; i<SIZE-repeat; i++) 17 { 18 if (a[i] > a[i+1]) 19 { 20 temp = a[i]; 21 a[i] = a[i+1]; 22 a[i+1] = temp; 23 } 24 } 25 }

  31. 7.2.4 버블 정렬: [프로그램7-5]의 개선 p.270 정렬이 완료된 상태라면 정렬을 끝내기 • 정렬 완료 여부 확인 방법 • 안쪽 for문에서 두 원소 간의 교환 발생 여부로 확인 가능 • 두 원소 간 교환이 발생했다. → 아직 정렬이 완료되었는지 알 수 없다. • 두 원소 간 교환이 발생한 적이 없다 → 정렬이 완료되었음을 의미 • 플래그(flag) 변수 • 프로그램의 특정 상태를 표시하고 상태 변화를 확인하는 데 사용하는 변수 • 예) 정렬이 완료된 상태인지 아닌지, 두 원소 간 교환이 발생했는지 아닌지, 입력이 완료되었는지 아닌지

  32. 7.2.4 버블 정렬: [프로그램7-5]의 개선 p.270 • 버블 정렬에서 플래그 변수의 사용법 • 플래그 변수 swap • 두 원소간 교환 발생 여부를 나타내는 데 사용 • swap == ‘N’ : 아직교환된 적이 없음 • swap== ‘Y’ : 교환이발생했음 • 안쪽 for문 시작 전에 초기화 swap = ‘N’; • 안쪽 for문에서 두 원소의 교환이 일어난다면 상태 변화를 저장 swap = ‘Y’; • 안쪽 for문 마친 후 swap을 확인하여 정렬의 완료 여부를 판단 swap이 여전히 ‘N’ →교환된 적이 없음 → 정렬 완료 의미 →정렬을 종료

  33. 프로그램 7-6 최적화한 버블 정렬 p.271 1 #include <stdio.h> 2 #define SIZE 5 3 4 int main() 5 { 6 int i, repeat, temp, b[SIZE] = {1, 2, 3, 5, 4}; 7 char swap; // 플래그 변수 두 원소간 정렬을 한 번만 반복하면 정렬이 완료된다.

  34. 프로그램 7-6 최적화한 버블 정렬 p.271 9 // 버블 정렬 시작 10 for (repeat=1; repeat<SIZE; repeat++) 11 { 12 swap = 'N';// 플래그 변수의 초기화 13 for (i=0; i<SIZE-repeat; i++) 14 { 15 if (b[i] > b[i+1]) 16 { 17 temp = b[i]; 18 b[i] = b[i+1]; 19 b[i+1] = temp; 20 21 swap = 'Y'; // 플래그 변수의 상태 변경 22 } 23 } 24 if (swap == 'N')// 플래그 변수 확인하기 25 break; // 정렬 작업을 끝내기 26 }

  35. 7.3 2차원 배열 p.272 • 2차원 배열 • 1차원 배열이 여러 개 모인 배열 • 표 형태의 구조로 표현되는 자료들을 저장하는 데 사용

  36. 7.3 2차원 배열 p.272

  37. 7.3.1 2차원 배열의 선언과 배열 원소 p.273 • 선언과 동시에 초기화하기 • int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}}; • {} 순서대로 한 행씩 초기화 • int matrix[ ][3] = {{1, 2, 3}, {4, 5, 6}}; • 초깃값 목록이 있으면 → 행의 개수 생략 가능 • 『주의』열 개수 생략 불가 • int matrix[ ][3] = {1, 2, 3, 4, 5, 6}; • 열수가 3이므로 int matrix[2][3]으로 해석됨

  38. 7.3.1 2차원 배열의 선언과 배열 원소 p.273 • 2차원 배열 원소 참조

  39. 7.3.2 2차원 배열과 반복문 p.273 • 2차원 배열은 1차원 배열의 배열 → 배열처리는 일반적으로 이중으로 중첩된 반복문을 이용 • matrix 배열을 다음과 같이 출력하기

  40. 7.3.3 2차원 배열의 입력: 행 단위 입력 p.275 같은 행 입력 시 행 첨자는 같고 열 첨자만 변함 • 2차원 배열의 행 단위 입력 1 for (row=0; row<2; row++) 2 { 3 for (col=0; col<3; col++) 4 { 5 printf("%d행 %d열? ", row, col); 6 scanf("%d", &matrix[row][col]); 7 } 8 }

  41. 7.3.3 2차원 배열의 입력: 열 단위 입력 p.276 같은 열 입력 시 열 첨자는 같고 행 첨자만 변함 • 2차원 배열의 열 단위 입력 1 for (col=0; col<3; col++) 2 { 3 for (row=0; row<2; row++) 4 { 5 printf("%d행 %d열? ", row, col); 6 scanf("%d", &matrix[row][col]); 7 } 8 } 1과 3행을 바꾸면 행 단위 입력이 됨

  42. 7.4.1 행렬의 덧셈 p.277 • 문제 • 입력 : 23행렬 A와 B • 출력: A와 B를 더한 행렬 C • 분석 • 행렬은 행과 열 수가 같아야 덧셈이 가능 → 세 행렬 A, B, C 모두 동일 크기의 2차원 배열 이용 • 각 대응 성분의 합이 결과 행렬의 성분 • 2차원 배열 처리 → 중첩 for문

  43. 7.4.1 행렬의 덧셈 p.277 • 해결 과정 • 행렬 A를 행 단위로 입력받기 (중첩 for문) • 행렬 B를 행 단위로 입력받기 (중첩 for문) • 행렬 C 행렬 A + 행렬 B (중첩 for문) C[i][j] = A[i][j] + B[i][j] (i= 0~1, j= 0~2) • 결과 행렬 C를 행 단위로 출력하기 (중첩 for문)

  44. 7-7: 2×3 행렬 A와 B의 덧셈 p.277 1 #include <stdio.h> 2 #define M 2 // 행 개수 매크로 상수 3 #define N 3 // 열 개수 매크로 상수 4 5 int main() 6 { 7 int A[M][N], B[M][N], C[M][N]; // M×N 행렬 배열 선언 8 int i, j; 9 10 // 행렬 A 입력 11 printf("\n행렬 A 입력 \n"); 12 for (i=0; i<M; i++) 13 for (j=0; j<N; j++) 14 { 15 printf("%d행 %d열? ", i+1, j+1); 16 scanf("%d", &A[i][j]); 17 } 18 19 // 행렬 B 입력은 10~17행에서 배열명만 B로 수정하면 됨 0행 0열 대신 이해하기 쉽게 1행 1열로 표시하기 위해

  45. 7-7: 2×3 행렬 A와 B의 덧셈 p.277 28 // 두 행렬의 합을 배열 C에 구하기 29 for (i=0; i<M; i++) 30 for (j=0; j<N; j++) 31 C[i][j] = A[i][j] + B[i][j]; 32 33 // 행렬 A 출력 34 printf("\n 행렬 A\n"); 35 for (i=0; i<M; i++) 36 { 37 printf(" [ "); 38 for (j=0; j<N; j++) 39 printf("%2d ", A[i][j]); 40 printf("] \n"); 41 } 42 43 //행렬 B/C 출력은 33~41행에서 배열명 해당 부분만 B/C로 변경하면 됨

  46. 7.5 char형 배열을 이용한 문자열 처리 p.280 7.5.1 char형 1차원 배열을 이용한 문자열 처리 • 문자열 상수 • “ ”로 묶어 놓은 연속된 문자들: “Seoul”, “Korea”, “Hong Gil Dong” • 문자열의 끝에는 널(null)이라는 ‘\0’ 문자가 있어야 함 → 문자열 상수는 기억장치에서 (“ ” 안의 문자수 + 1) 바이트로 표현됨

  47. 7.5.1 char형 1차원 배열을 이용한 문자열 처리 p.280 • 문자열 상수를 저장하려면? • char형 변수  문자 상수 즉 한 개의 문자만 저장 가능 • 문자열은 char형 1차원 배열이 필요 • 그림 7-21 • 문자열에 포함할 최대 문자수로서 (실제 문자수+ 널문자1)개 이상 chars[6] = “Seoul”; s 문자열의 끝을 나타내는 널문자

  48. 7.5.1 char형 1차원 배열을 이용한 문자열 처리 • 문자열을 저장할 배열 선언 p.281 • ㈜ 배열의 크기 • 문자열에 포함된 문자의 수보다 최소한 한 개 더 많아야 함 (∵) 널문자 ‘\0’ 저장 • 예) • char c[6]; 널문자를 제외한 최대 5개 문자 저장 • char c[6] = {'S', 'e', 'o', 'u', 'l'}; • char c[6] = "Seoul";

  49. 7.5.1 char형 1차원 배열을 이용한 문자열 처리 p.281 공백 문자 입력 전까지를 문자열로 저장 배열에 저장된 문자열을 출력 • scanf/printf를 이용한 문자열의 입출력 • ㈜배열명 자체가 배열의 시작 주소(8장 참고) • 입력 시 배열명 앞에 &를 사용하지 않음 (& 사용 시 결과 예측 불가) • 형식 scanf(“%s”, char형 1차원 배열명); printf(“%s”, char형 1차원 배열명); • char city[10] = "Seoul"; • printf("City: %s", city); • scanf("%s", city); • 『주의』 • city 입력시‘San Francisco’로 입력하면?

  50. 7.5.1 char형 1차원 배열을 이용한 문자열 처리 p.282 엔터키 입력 전까지의 모든 문자를 배열에 저장 • 문자열 전용 입력 함수 gets scanf와 달리 공백을 포함한 문자열 입력 가능 • 형식 gets(char형 1차원 배열명); • 예 char name[12]; // 널문자를 제외한 11개의 문자를 저장할 수 있는 배열 선언 gets(name); // 실행할 때 입력되는 문자열이 name에 저장됨 &name은 에러

More Related