본 포스팅은 C++로 시작하는 객체지향 프로그래밍 책을 바탕으로 작성하였습니다.
C++로 시작하는 객체지향 프로그래밍
『C++로 시작하는 객체지향 프로그래밍』은 구문보다는 문제 해결에 중점을 두는 문제 구동 방식을 사용한 프로그래밍에 대해 가르치고 있다. 여러 가지 상황에서 문제를 야기한 개념을 사용함
book.naver.com
key point
- 배열(array) : 많은 데이터의 모음을 저장할 수 있다.
7.2 배열의 기초
- 배열은 같은 유형의 많은 값들을 저장할 때 사용된다. 배열의 요소는 인덱스를 사용하여 접근이 가능하다.
7.2.1 배열 선언
- 배열의 크기는 상수여야 한다.
//잘못된 것
int size = 4;
double myList[size]
//옳은 것
const int size = 4;
double myList[size]
7.2.2 배열 요소 접근
- 베열 인덱스는 0부터 시작
- 배열을 선언할 때 요소의 수를 나타내기 위해서 크기 선언자(size declarator)가 사용된다.
- 배열 인덱스 -> 배열에서 특정 요소에 접근
- 범위 초과 오류 주의 (배열의 크기를 넘어서는 인덱스 사용)
7.2.3 배열 초기화
- 하나의 문장으로 배열을 선언하고 초기화할 수 있다.
- 배열 선언과 초기화는 동시에 해야 한다. 분리는 잘못된 것으로 구문 오류 발생
- 동시에 할 때는 배열의 크기를 생략해도 된다.
double myList[] = {1.9, 2.9, 3.4, 3.5)
//배열의 크기를 생략하면 컴파일러가 자동으로 배열 요소의 수를 지정한다.
- 배열의 일부분만 초기화하는 것도 가능하다.
7.2.4 배열 처리
- 배열의 모든 요소는 같은 유형이다. 각 요소에 대해 반복문을 사용하여 동일한 방법으로 처리가 가능하다.
- 배열의 크기를 이미 알고 있으므로 for문을 사용하기에 적당하다.
//다음과 같은 배열을 선언했다고 가정
const int ARRAY_SIZE = 10;
double myList[ARRAY_SIZE];
1. 입력 값으로 배열 초기화
cout << "Enter " << ARRAY_SIZE << " values: ";
for (int i = 0; i < ARRAY_SIZE; i++)
cin >> myList[i];
2. 임의의 값으로 배열 초기화
for (int i = 0; i < ARRAY_SIZE; i++)
{
myList[i] = rand() % 100;
}
3. 배열 출력
for(int i = 0; i < ARRAY_SIZE; i ++)
{
cout << myList[] << " " << endl;
}
4. 배열 복사
//myList라는 배열을 list로 옮길려면?
//잘못된 방법
list = myList;
//옳은 방법
for (int i = 0; i < ARRAY_SIZE; i++)
{
list[i] = myList[i];
}
5. 모든 요소의 합
double total = 0;
for (int i = 0; i < ARRAY_SIZE; i++)
{
total += myList[i];
}
6. 배열의 최댓값 구하기
double max = myList[0];
for (int i = 0; i < ARRAY_SIZE; i++)
{
if (mtList[i] > max)
max = myList[i];
}
7. 최댓값 요소의 가장 작은 인덱스 구하기
double max = mtList[0]'
int indexOfMax = 0;
for (int i = 0; i < ARRAY_SIZE; i++)
{
if ( max < myList[i] )
{
max = myList[i];
indexOfMax = i;
}
}
8. 요소 임의로 섞기 (무작위로 재배치시켜야 하는 경우 shuffling)
srand(time(0));
for (int i = ARRAY_SIZE; i > 0; i--)
{
//0 <= j <= i에 대해 무작위로 인덱스 j 생성
int j = rand() % (i + 1);
//myList[i]와 myList[j] 교환
double temp = myList[i];
myList[i] = myList[j];
myList[j] = temp;
}
9. 요소 시프트 이동
double temp = myList[0];
//오 -> 왼
for (int i = 1; i < ARRAY_SIZE; i++)
{
myList[i-1] = myList[i];
}
myList[ARRAY_SIZE - 1] = temp;
10. 코드 간략화
string months[] = {"January", "February", ... , "December"};
cout << "Enter a month number(1 to 10) : ";
int monthNumber;
cin >> monthNumber;
cout << "The month is " << months[monthNumber - 1] << endl;
7.5 함수로 배열 전달
- 배열 인수가 함수로 전달될 때 배열의 시작 주소가 함수의 배열 매개변수로 전달된다. 배개변수와 인수 모두 같은 배열을 참조하게 된다. (공유에 의한 전달)
#include <iostream>
using namespace std;
void m(int, int[]);
int main()
{
int x = 1;
int y[10];
y[0] = 1;
m(x, y);
cout << "x is " << x << endl;
cout << "y is " << y[0] << endl;
return 0;
}
void m(int number, int numbers[])
{
number = 1001; //number값에 새 값 대임
numbers[0] = 5555; //numbers[0]에 새 값 대입
}
//x is 1
//x와 number은 서로 다른 변수라서 1이 출력
//y is 5555
//y와 numbers는 같은 배열을 참조하고 있기 때문에 y[0] = 5555 (별칭으로 작용)
7.6 함수에서의 배열 인수 보호
함수의 배열 매개변수 값이 변경되지 않도록 하기 위해 함수에서 const 배열 매개변수를 정의할 수 있다.
#include <iostream>
using namespace std;
void p(const int list[], int arraySize)
{
//실수로 배열 값을 수정
list[0] = 100; //컴파일 오류
}
int main()
{
int number[5] = {1, 4, 3, 6, 8};
p(number, 5);
return 0;
}
7.7 함수로부터 배열 반환
함수에서 배열을 반환하기 위해서는 함수의 매개변수로 전달한다.
#include <iostream>
using namespace std;
void reverse(const int list[], int newList[], int size);
void printArray(const int list[], int size);
int main()
{
const int SIZE = 6;
int list[] = { 1, 2, 3, 4, 5, 6 };
int newList[SIZE];
reverse(list, newList, SIZE);
cout << "The original array: ";
printArray(list, SIZE);
cout << endl;
cout << "The reversed array: ";
printArray(newList, SIZE);
cout << endl;
return 0;
}
void reverse(const int list[], int newList[], int size)
{
for (int i = 0, j = size - 1; i < size; i++, j--)
{
newList[j] = list[i];
}
}
void printArray(const int list[], int size)
{
for (int i = 0; i < size; i++)
cout << list[i] << " ";
}
//The original array: 1 2 3 4 5 6
//The reversed array: 6 5 4 3 2 1
7.9 배열 탐색
* 배열이 정렬되어 있다면 배열 요소를 찾는 경우 선형 탐색보다 이진 탐색이 더 효율적이다.
* 탐색(searching) : 배열에서 특정 요소를 찾는 작업
- 선형 탐색
주요 요소를 키(key)로 하고, 이 키와 배열 내의 모든 요소를 연속적으로 비교하여 검색하는 방법
*장점 : 배열 크기가 작은 경우나 정렬이 되지 않는 경우 유용
*단점 : 큰 배열에서는 비효율
int linearSeach(const int list[], int key, int arraySize)
{
for (int i = 0l i < arraySize; i++)
{
if (key == list[i])
return i;
}
return -1;
}
- 이진탐색
미리 오름차순으로 정렬된 배열을 가정.
배열 중앙 요소와 키(key)를 비교하는 것으로 시작하여 다음 세 경우에 따라 데이터 목록을 검색해 나간다.
- 키가 중앙값보다 작다면, 배열의 앞쪽 절반에서 탐색을 계속한다.
- 키가 중앙값과 같다면 원하는 키 값을 찾은 것이며, 탐색을 끝낸다.
- 키가 중앙값보다 크면, 배열의 뒤쪽 절반에서 탐색을 계속한다.
#include <iostream>
using namespace std;
int binarySearch(const int[], int, int);
int main()
{
int list[] = { 2, 4, 7, 10, 11, 16, 21, 27, 33, 39, 45, 48, 50, 59, 60, 66, 69, 70, 79, 84 };
int i = binarySearch(list, 20, 16);
int j = binarySearch(list, 20, 9);
int k = binarySearch(list, 20, 66);
cout << i << " " << j << " " << k << endl;
return 0;
}
int binarySearch(const int list[], int listSize, int key)
{
int low = 0;
int high = listSize - 1;
int count = 0;
while (high >= low)
{
count++;
int mid = (low + high) / 2;
if (key == list[mid])
{
cout << "count: " << count << endl;
return mid;
}
else if (key < list[mid])
high = mid - 1;
else
low = mid + 1;
}
cout << "count: " << count << endl;
return -1;
}
//i = 4
7.10 배열 정렬
- 탐색과 마찬가지로 정렬도 컴퓨터 프로그래밍에서 자주 사용되는 기법으로, 많은 정렬 알고리즘이 개발되어 있다.
- 선택 정렬을 사용하여 오름차순으로 목록 정리 : 선택 정렬은 반복적으로 가장 작은 수를 선택하여 남아 있는 목록의 첫 번째 수와 교환한다.
#include <iostream>
using namespace std;
void selectionSort(double list[], int listSize)
{
for (int i = 0; i < listSize - 1; i++)
{
double currentMin = list[i];
int currentMInIndex = i;
for (int j = i+1; j < listSize; j++)
{
//내림차순 할꺼면 부등호방향 반대
if (currentMin > list[j])
{
currentMin = list[j];
currentMInIndex = j;
}
}
//필요하다면 list[i]와 list[currentMinIndex] 교화
if (currentMInIndex != i)
{
list[currentMInIndex] = list[i];
list[i] = currentMin;
}
}
for (int i = 0; i < listSize; i++)
{
cout << list[i] << " ";
}
}
int main()
{
double list[] = { 1, 9, 4.5, 6.6, 5.7, -4.5 };
selectionSort(list, 6);
return 0;
}
//-4.5 1 4.5 5.7 6.6 9
list
list 7.1 평균 구하기, 평균보다 큰 값의 개수 구하기
#include <iostream>
using namespace std;
int main()
{
const int NUMBERS_OF_ELEMENTS = 10;
double numbers[NUMBERS_OF_ELEMENTS];
double sum = 0;
for (int i = 0; i < NUMBERS_OF_ELEMENTS; i++)
{
cout << "Enter a new number : ";
cin >> numbers[i];
sum += numbers[i];
}
double average = sum / NUMBERS_OF_ELEMENTS;
int count = 0;
for (int i = 0; i < NUMBERS_OF_ELEMENTS; i++)
{
if (numbers[i] > average)
count++;
}
cout << "Average is " << average << endl;
cout << "Number od elements above the average " << count << endl;
return 0;
}
/*
Enter a new number : 1
Enter a new number : 2
Enter a new number : 3
Enter a new number : 4
Enter a new number : 5
Enter a new number : 6
Enter a new number : 7
Enter a new number : 8
Enter a new number : 9
Enter a new number : 10
Average is 5.5
Number od elements above the average 5
*/
list 7.2 복권번호
#include <iostream>
using namespace std;
int main()
{
bool isCovered[9];
int number;
//1부터 9 false 초기화
for (int i = 0; i < 9; i++)
{
isCovered[i] = false;
}
//숫자 입력 받은 것들 true 초기화
cin >> number;
while (number != 0)
{
isCovered[number - 1] = true;
cin >> number;
}
//모든 숫자가 존재하는지 검사
bool allCovered = true;
for (int i = 0; i < 9; i++)
{
if (!isCovered[i])
{
allCovered = false;
break;
}
}
//결과출력
if (allCovered)
cout << "The tickets cover all numbers." << endl;
else
cout << "The tickets don't cover all numbers." << endl;
return 0;
}
//2 5 6 5 4 3 2 4 2 0
//The tickets don't cover all numbers.
list 7.3 DeckOfCards
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
int main()
{
const int NUMBER_OF_CARDS = 52; //배열 크기 선언
int deck[NUMBER_OF_CARDS]; //배열 선언
string suits[] = { "Spades", "Hearts", "Diamonds", "Clubs" };
string ranks[] = { "Ace", "2", "3", "4","5","6","7","8","9","10","Jack","Queen","king" };
//카드 초기화
for (int i = 0; i < NUMBER_OF_CARDS; i++)
{
deck[i] = i;
}
//카드 섞기
srand(time(0));
for (int i = 0; i < NUMBER_OF_CARDS; i++)
{
int index = rand() % NUMBER_OF_CARDS;
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
//앞서부터 4개의 카드 출력
for (int i = 0; i < 4; i++)
{
string suit = suits[deck[i] / 13];
string rank = ranks[deck[i] % 13];
cout << "Card number " << deck[i] << " : " << rank << " of " << suit << endl;
}
return 0;
}
/*
Card number 6 : 7 of Spades
Card number 16 : 4 of Hearts
Card number 41 : 3 of Clubs
Card number 7 : 8 of Spades
*/
list 7.8 각 문자의 발생 빈도 계산
#include <iostream>
#include <ctime> //time함수 사용
using namespace std;
const int NUMBER_OF_LETTERS = 26;
const int NUMBER_OF_RANDOM_LETTERS = 100;
void createArray(char []);
void displayArray(const char[]);
void countLetters(const char[], int[]);
void displayCounts(const int[]);
int main()
{
//배열 선언와 생성
char chars[NUMBER_OF_RANDOM_LETTERS];
//임의의 소문자 배열 초기화
createArray(chars);
//배열 출력
cout << "The lowercase letters are: " << endl;
displayArray(chars);
//각 문자의 빈도수 계산
int counts[NUMBER_OF_LETTERS];
//각 문자의 빈도수 계산
countLetters(chars, counts);
//결과 출력
cout << "\nThe occurrences od each letter are: " << endl;
displayCounts(counts);
return 0;
}
//문자 배열
//임의의 소문자로 배열 초기화
void createArray(char chars[])
{
srand(time(0));
for (int i = 0; i < NUMBER_OF_RANDOM_LETTERS; i++)
{
chars[i] = static_cast<char>('a' + rand() % ('z' - 'a' + 1));
}
}
//문자 배열 출력
void displayArray(const char chars[])
{
for (int i = 0; i < NUMBER_OF_RANDOM_LETTERS; i++)
{
if ((i + 1) % 20 == 0)
cout << chars[i] << " " << endl;
else
cout << chars[i] << " ";
}
}
//각 문자에 대한 빈도수 계산
void countLetters(const char chars[], int counts[])
{
//배열 초기화
for (int i = 0; i < NUMBER_OF_LETTERS; i++)
counts[i] = 0;
//배열의 각 소문자에 대한 빈도수 계산
for (int i = 0; i < NUMBER_OF_RANDOM_LETTERS; i++)
{
counts[chars[i] - 'a']++;
}
}
//결과출력
void displayCounts(const int counts[])
{
for (int i = 0; i < NUMBER_OF_LETTERS; i++)
{
if ((i + 1) % 10 == 0)
cout << counts[i] << " " << static_cast<char>(i + 'a') << endl;
else
cout << counts[i] << " " << static_cast<char>(i + 'a') << " ";
}
}
/*
The lowercase letters are:
f d z i w s p p g u c b o u w z e b s g
u s m m n h r g e o p r u z e m a i c m
n e z m q j z m k g m y z l j n g g p v
u h h u k s t q c n s t p q l a q r y v
m t l v m p b b t q p g z d p c i u a d
The occurrences od each letter are:
3 a 4 b 4 c 3 d 4 e 1 f 7 g 3 h 3 i 2 j
2 k 3 l 9 m 4 n 2 o 8 p 5 q 3 r 5 s 4 t
7 u 3 v 2 w 0 x 2 y 7 z
*/
프로그래밍 실습
7.2 역순으로 출력
//역순으로 출력_함수사용
#include <iostream>
using namespace std;
void reverse(int list[], int size);
int main()
{
const int SIZE = 10;
int list[SIZE];
cout << "10개의 숫자를 입력하시오 : ";
for (int i = 0; i < SIZE; i++)
{
int num;
cin >> num;
list[i] = num;
}
cout << "The reverse array: ";
reverse(list, SIZE);
cout << endl;
return 0;
}
void reverse(int list[], int size)
{
for (int i = 0; i < size / 2; i++)
{
int temp = list[i];
list[i] = list[size - 1 - i];
list[size - 1 - i] = temp;
}
for (int i = 0; i < size; i++)
{
cout << list[i] << " ";
}
}
/*
10개의 숫자를 입력하시오 : 1 2 3 4 5 6 7 8 9 10
The reverse array: 10 9 8 7 6 5 4 3 2 1
*/
#include <iostream>
using namespace std;
int main()
{
const int SIZE = 10;
int list[SIZE];
for (int i = 0; i < SIZE; i++)
{
cout << "숫자를 입력해주세요: ";
cin >> list[i];
}
for (int i = SIZE-1; i >= 0; i--)
{
cout << list[i] << " ";
}
return 0;
}
/*
숫자를 입력해주세요: 1
숫자를 입력해주세요: 2
숫자를 입력해주세요: 3
숫자를 입력해주세요: 4
숫자를 입력해주세요: 5
숫자를 입력해주세요: 6
숫자를 입력해주세요: 7
숫자를 입력해주세요: 8
숫자를 입력해주세요: 9
숫자를 입력해주세요: 10
10 9 8 7 6 5 4 3 2 1
*/
7.4 점수 분석
#include <iostream>
using namespace std;
int main()
{
const int SIZE = 100;
double score[SIZE];
double sum = 0;
int count = 0;
do
{
cout << "Enter a new score : ";
cin >> score[count];
if (score[count] >= 0)
sum += score[count];
}
while (score[count++] >= 0);
double average = sum / (count - 1);
int up = 0;
int down = 0;
for (int i = 0; i < count - 1; i++)
{
if (score[i] >= average)
up++;
else
down++;
}
cout << "평균값은 " << average << endl;
cout << "평균과 같거나 큰 점수의 수는 " << up << endl;
cout << "평균보다 작은 점수의 수는 " << down << endl;
return 0;
}
/*
Enter a new score : 40
Enter a new score : 50
Enter a new score : 60
Enter a new score : -10
평균값은 50
평균과 같거나 큰 점수의 수는 2
평균보다 작은 점수의 수는 1
*/
7.8 배열 평균
#include <iostream>
using namespace std;
int average(int array[], int size) //int배열은 int
{
int total = 0;
for (int i = 0; i < size; i++)
total += array[i];
return (total / size);
}
double average(double array[], int size) //double 배열은 double
{
int total = 0;
for (int i = 0; i < size; i++)
total += array[i];
return (total / size);
}
int main()
{
const int SIZE = 10;
double list[SIZE];
cout << "10개의 점수를 입력해주세요: ";
for (int i = 0; i < SIZE; i++)
{
cin >> list[i];
}
cout << "평균값은 " << average(list, SIZE) << endl;
return 0;
}
//10개의 점수를 입력해주세요: 1 2 3 4 5 6 7 8 9 10
//평균값은 5
7.9 최솟값 찾기
#include <iostream>
using namespace std;
double min(double array[], int size)
{
double mini = array[0];
for (int i = 0; i < size; i++)
{
if (mini > array[i])
mini = array[i];
}
return mini;
}
int main()
{
const int SIZE = 10;
double list[SIZE];
cout << "Enter ten minutes: ";
for (int i = 0; i < SIZE; i++)
{
cin >> list[i];
}
cout << "The minimum number is " << min(list, SIZE) << endl;
return 0;
}
//Enter ten minutes: 1.9 25. 3.7 2 1.5 6 3 4 5 2
//The minimum number is 1.5
7.10 최소값 요소의 인덱스 찾기
#include <iostream>
using namespace std;
//함수 원형
int indexOfSmallestElement(double array[], int size);
//main 함수
int main() {
//배열 크기 선언하기
const int x = 10;
double list[x];
//배열 초기화
for (int i = 0; i < x; i++)
{
cin >> list[i];
}
//출력하기
cout << "최소값의 인덱스는 " << indexOfSmallestElement(list, x) << endl;
return 0;
}
//최소값 요소의 인덱스 반환 함수
int indexOfSmallestElement(double array[], int size)
{
double min = array[0];
int index = 0;
for (int i = 0; i < size; i++)
{
if (min > array[i])
{
min = array[i];
index = i;
}
}
return index;
}
//22 92 18 48 73 38 18 29 56 98
//최소값의 인덱스는 2
7.16 선택 정렬 수정
#include <iostream>
using namespace std;
void selectionSort(double list[], int size)
{
for (int i = size - 1; i > 0; i--)
{
int maxIndex = i;
double max = list[i];
for (int j = 0; j < i; j++)
{
if (max < list[j])
{
max = list[j];
maxIndex = j;
}
}
if (maxIndex != i)
{
list[maxIndex] = list[i];
list[i] = max;
}
}
for (int i = 0; i < size; i++)
{
cout << list[i] << " / ";
}
}
int main()
{
const int SIZE = 10;
double list[SIZE] = { 1, 9, 4.5, 6.6, 5.7 ,-4.5, 2, -1.1, 5.2, -3.7 };
selectionSort(list, SIZE);
return 0;
}
//-4.5 / -3.7 / -1.1 / 1 / 2 / 4.5 / 5.2 / 5.7 / 6.6 / 9 /
'Language > C++' 카테고리의 다른 글
[C++_제 17장] 재귀 호출 (0) | 2021.12.09 |
---|---|
[C++_제 8장] 다차원 배열 (0) | 2021.12.09 |
[C++_제 6장] 함수 (0) | 2021.11.23 |
[C++_백준] if문 ( 1330, 9498, 2753, 14681, 2884 ) (0) | 2021.11.08 |
[C++_제 5장] 반복문 (0) | 2021.10.09 |