vectors and arrays

Post on 05-Jan-2016

40 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Vectors and Arrays. Prof. Jung Guk Kim HUFS, jgkim@hufs.ac.kr. 목표. 객체의 집합으로서 벡터의 사용에 친숙해진다 . 벡터의 원소에 접근하는 것과 벡터 크기를 재조정한다 . 벡터를 함수 인자로 사용한다 . 자주 쓰는 배열 알고리즘에 대해 배운다 . 일차원과 이차원 배열의 사용 방법을 배운다. 벡터를 이용한 데이터 아이템 집합 표현. 모든 급여를 읽어서 리스트를 출력하는 프로그램을 가정하자 프로그램은 최고 급여액을 아래와 같이 표시한다 . 32000 - PowerPoint PPT Presentation

TRANSCRIPT

Vectors and Arrays

Prof. Jung Guk Kim

HUFS,

jgkim@hufs.ac.kr

RTDCS Lab.

목표

객체의 집합으로서 벡터의 사용에 친숙해진다 . 벡터의 원소에 접근하는 것과 벡터 크기를 재조정한다 . 벡터를 함수 인자로 사용한다 . 자주 쓰는 배열 알고리즘에 대해 배운다 . 일차원과 이차원 배열의 사용 방법을 배운다 .

RTDCS Lab.

벡터를 이용한 데이터 아이템 집합 표현

모든 급여를 읽어서 리스트를 출력하는 프로그램을 가정하자 프로그램은 최고 급여액을 아래와 같이 표시한다 .

32000

54000

67500

29000

35000

80000

highest value => 115000

44500

100000

65000

최고 급여액을 찾기 위해서는 먼저 프로그램은 급여를 읽어야 한다 . 만약 회사에 10 명의 직원이 있다는 것을 알고 있다면 10 개의 변수

salary1, salary2, ... , salary10. 연속적인 변수를 만들어 사용하는 것은 실질적이지 못하다 .

직원이 100 명 이상일 수도 있기 때문이다 .

RTDCS Lab.

벡터를 이용한 데이터 아이템 집합 표현

벡터 (vector) 란 같은 타입의 데이터 아이템의 집합이다 . vector<double> salaries(10);

여기서 salaries 는 연속된 double 타입의 값을 저장한다 .

또 (10) 벡터의 값을 10 개 까지 저장한다는 것을 나타낸다 .

RTDCS Lab.

벡터를 이용한 데이터 아이템 집합표현

구문 9.1 벡터 변수의 정의

RTDCS Lab.

벡터를 이용한 데이터 아이템 집합 표현

Salaries 속에 데이터를 넣으려면 벡터의 어느 칸에 넣는지를 명시해 주어야 한다 . 이를 위해 [] 연산자를 사용한다 .

salaries[4] = 35000; 그림의 숫자는 각 내부의 칸 를 나타내는 index 이다 . salaries 벡터 (vector) 는 double 타입의 값을 가진다 ,

따라서 salaries[4] 에는 오직 double 타입의 값만을 가질 수 있다 .

cout << salaries[4] << "\n";

RTDCS Lab.

벡터를 이용한 데이터 아이템 집합 표현

C++ 벡터의 칸은 0 부터 시작하게 번호가 붙여진다 .

RTDCS Lab.

벡터를 이용한 데이터 아이템 집합 표현

RTDCS Lab.

벡터 첨자

벡터에서 존재하지 않는 칸에 접근 ( 읽기 / 쓰기 ) 한다면 오류가 발생한다 . .

vector<double> staff(10);

cout << staff[10]; /* legal subscripts are 0 until 9 */ 만양 index 에러가 발생한다면 , 잘못된 위치에서 값을

접근 ( 읽기 / 쓰기 ) 한 경우가 발생한다 . 자주 발생하는 오류는 벡터의 크기를 명시하지 않을 경우

(no elements.)

vector<double> salaries; /* no size given */

salaries[0] = 35000;

RTDCS Lab.

벡터 첨자

벡터의 크기는 size 함수를 이용하여 알아낼 수 있다 .

for(i = 0; i < v.size(); i++)

do something with v[i]; size 를 사용하는 것은 magic number 사용하는 것 보다

좋은 생각이다 . (see Quality Tip 2.3).

RTDCS Lab.

벡터 첨자

push_back 함수는 벡터를 처음에는 빈 벡터를 만들고 직원이 추가될 때마다 벡터가 늘어나게 한다 .

vector<double> salaries;

. . .

double s;

cin >> s;

. . .

salaries.push_back(s);

RTDCS Lab.

벡터 첨자

push_back 명령은 벡터의 크기를 틀려 한 원소를 벡터의 뒤에 추가한다 .

벡터에서 사용될 원소가 몇 개나 될지 미리 알 수 있다면 벡터를 정의할 때 크기를 명시하고 필요할 때 사용한다 .

또 다른 멤버 함수로 pop_back, 이 함수는 벡터의 마지막 원소를 없애고 크기를 하나 줄인다 .

salaries.pop_back(); /* Now salaries has size 9 */ ANSI 표준에서는 벡터와 관련해서 더 많은 유용한

함수를 정의하고 있다 . 그러나 이 책에서는 push_back 과 pop_back 만을 사용하기로 한다 .

RTDCS Lab.

벡터 첨자 (salvect.cpp)

RTDCS Lab.

벡터 첨자 (salvect.cpp)

RTDCS Lab.

벡터 인자와 반환값 (Vector Parameters) 함수나 프로시저는 벡터를 인자로 갖게 되는 경우가 종종

있다 .

double average(vector<double> v)

{

if (v.size() == 0) return 0;

double sum = 0;

for (int i = 0; i < v.size(); i++)

sum = sum + v[i];

return sum / v.size();

}

RTDCS Lab.

벡터 인자와 반환값 (Vector Parameters) 벡터는 passed by value or by reference Pass by reference 를 사용한다면 벡터에 있는

개별원소는 변경될 것이다 .

void raise_by_percent(vector<double>& v, double p)

{

for (int i = 0; i < v.size(); i++)

v[i] =v[i] * (1 + p / 100);

}

RTDCS Lab.

벡터 인자와 반환값 (Return Values)

함수는 벡터를 반환할 수 있다 . 이 함수는 특정 범위의 값을 포함하는 집합을 돌려준다

vector<double> between(vector<double> v, double low, double high) { vector<double> result; for (int i = 0; i < v.size(); i++) if (low <= v[i] && v[i] <= high) result.push_back(v[i]); return result;}

RTDCS Lab.

벡터 인자와 반환값 (Return Values)

이 함수는 범위에 포함되는 값의 위치 (index) 값의 집합을 돌려준다 . vector<int> find_all_between(vector<double> v, double low, double high) { vector<int> pos; for (int i = 0; i < v.size(); i++) { if (low <= v[i] && v[i] <= high) pos.push_back(i); } return pos; }

RTDCS Lab.

벡터 인자와 반환값 (matches.cpp)

RTDCS Lab.

벡터 인자와 반환값 (matches.cpp)

RTDCS Lab.

원소의 삭제와 삽입

어떻게 벡터의 한 원소를 삭제할 것인가 ? 만약 벡터 속에서 삭제하려는 원소가 특별한 순서에 따라

들어 있는 것이 아니라면 삭제는 간단하다 .

void erase(vector<string>& v, int pos){

int last_pos - v.size() - 1;

v[pos] = v[last_pos];

v.pop_back();

}

RTDCS Lab.

원소의 삭제와 삽입

void erase(vector<string>& v, int pos)

{

for (int i = pos; i < v.size() - 1; i++)

v[i] = v[i+1];

v.pop_back();

}

RTDCS Lab.

원소의 삭제와 삽입

원소를 삽입할 때 벡터의 중간에 삽입한다면 , 새로운 벡터의 원소를 벡터의 마지막에 추가한다 . 그리고 모든 원소를 추가하는 원소 아래로 이동한다 .

void insert(vector<string>& v int pos, string s)

{

int last = v.size() - 1;

v.push_back(v[last]);

for (int i = last; i > pos; i--)

v[i] = v[i - 1];

v[pos] = s;

}

RTDCS Lab.

원소의 삭제와 삽입

원소를 삽입 할 때는 벡터의 제일 끝 원소부터 삽입하려는 위치까지 차례로 올라가면서 옮긴다 .

RTDCS Lab.

병렬 벡터

일련의 상품 데이터를 처리하고 , 상품 정보와 상품 가치( 점수 / 가격비 ) 가 가장 높은 상품을 표시해 보자

RTDCS Lab.

병렬 벡터

동일 길이의 세개의 벡터를 생성 (names, price, scores) (See bestval1.cpp)

이러한 벡터를 parallel vectors 함께 작업하기 때문이다 .

각 slice - names[i], prices[i], scores[i] - 언제나 함께 처리된다 .

RTDCS Lab.

병렬 벡터 (bestval1.cpp)

RTDCS Lab.

병렬 벡터 (bestval1.cpp)

RTDCS Lab.

병렬 벡터 (bestval1.cpp)

RTDCS Lab.

병렬 벡터

대형 프로그램에서 병렬 벡터는 많은 문제를 발생 시킨다 . 각 벡터의 길이가 같은지 . 같은 위치의 원소에 들어가는 값들이 실제로 한곳에서

나온 값인지 모든 벡터의 같은 위치 원소를 처리하는 함수를

호출할 때 모든 벡터의 원소를 인자로 잡아 주어야 한다 .

같은 원소를 함께 묶어 그 것이 나타내는 의미 ( 개념 ) 을 찾는다 . 그 의미 ( 개념 ) 을 클래스로 만든다 .

병렬 벡터 집합에서의 집합은 한 벡터로 대치될 수 있다 .

RTDCS Lab.

병렬 벡터

RTDCS Lab.

병렬 벡터 (bestval2.cpp)

RTDCS Lab.

병렬 벡터 (bestval2.cpp)

RTDCS Lab.

병렬 벡터 (bestval2.cpp)

RTDCS Lab.

병렬 벡터 (bestval2.cpp)

RTDCS Lab.

배열 (array)

같은 타입의 원소를 모아 두는 두 번째 방법으로 배열(arrays) 이 있다 .

배열은 벡터에 비해 저수준의 추상화 개념으로 그만큼 사용하기 불편하다 . 배열은 크기 재조정이 불가능하다 .

벡터는 최근에 C++ 에 추가된 개념이고 , 예전의 많은 프로그램들이 배열을 사용하고 있다 .

배열은 벡터에 비해 빠르고 효율적이다 .

RTDCS Lab.

배열 (array)

배열의 정의는 벡터의 정의와 유사하다 .

double salaries[10]; /* array */

/* compare to.... */

vector<double> salaries(10);

배열은 크기를 변경시킬 수 없다 . 배열의 크기는 반드시 컴파일 할 때 설정되어 있어야

한다 .

RTDCS Lab.

배열 (array)

배열을 사용할 때는 프로그램에서 저장하게 될 최대 원소 수를 잘 예측하여야 한다 .

const int SALARIES_CAPACITY = 100;

double salaries[SALARIES_CAPACITY];

여기서 상수는 배열의 용량 (capacity) 을 나타낸다 .

RTDCS Lab.

배열 (array) 얼마나 많은 원소가 사용되고 있는가를 알려면짝 변수 (companion

variable) 를 가지고 있어야 한다 . int salaries_size = 0; while (more && salaries_size < SALARIES_CAPACITY) {

cout << "Enter salary or 0 to quit: "; double x; cin >> x; if (cin.fail() || x == 0) more = false; else {

salaries[salaries_size] = x; salaries_size++;

} }

RTDCS Lab.

배열 (array)

RTDCS Lab.

배열 인자 (Array Parameters)

배열 인자를 갖는 함수를 만들 때는 비어 있는 괄호 [] 를 인자 이름 뒤에 오게 한다 .

double maximum(double a[], int a_size);

배열의 크기도 함수에 인자로 보낼 필요가 있다 . 배열에는 size() 와 같은 멤버 함수가 없기 때문에 함수에서 배열의 크기를 알 수 없다 .

RTDCS Lab.

배열 인자 (Array Parameters)

다른 인자와는 달리 배열 인자는 항상 참조에 의한 전달passed by reference 로 보내진다 . void raise_by_percent(double s[], double s_size, double p) {

int i; for (i = 0; i < s_size; i++)

s[i] = s[i] * (1 + p / 100); }

배열 인자를 정의할 때는 & 부호를 사용하지 않는다 . 함수가 배열을 수정하지 않는다면 const 키워드를

추가하는 것이 좋다 . double maximum(const double a[], int a_size)

RTDCS Lab.

배열 인자 (Array Parameters) 함수에서 배열에 원소를 추가하려면 , 함수에 배열 , 배열의

최대 크기 , 현재 크기 세개의 인자를 보내야 한다 . 현재의 크기는 함수가 수정할 수 있게 참조 인자로

전달되어야 한다 . void read_data(double a[], int a_capacity, int& a_size) {

a_size = 0; while (a_size < a_capacity) { double x; cin >> x; if (cin.fail()) return; a[a_size] = x; a_size++; }

}

RTDCS Lab.

배열 인자 (Array Parameters) 배열이 함수의 반환 타입은 될 수 없다 .

함수에서 여러 값을 계산하려면 함수 호출 프로그램은 결과를 저장할 배열 인자를 함수에 보내야 한다 .

RTDCS Lab.

배열 인자 (salarray.cpp)

RTDCS Lab.

배열 인자 (salarray.cpp)

RTDCS Lab.

배열 인자 (salarray.cpp)

RTDCS Lab.

문자 배열 (Character Arrays)

C++ 에 string class 가 없었다 . 모든 문자열 처리는 char 타입의 배열을 이용하여

이루어 졌다 . 한 문자 상수는 다음과 같이 작은 따옴표 (single quotes)

로 표시한다 .

char input = 'y'; /* don't confuse with "y" */

문자열 (string) 을 저장하는 배열의 정의이다 .

char greeting[] = "Hello";

/* same as greeting[6] = "Hello"; */

RTDCS Lab.

문자 배열 (Character Arrays)

이 배열에는 '\0'(zero terminator) 라는 문자가 들어 있다 .

문자 배열 변수를 문자 배열 상수로 초기화 할 때는 문자 배열의 크기를 생략해도 된다 .

RTDCS Lab.

문자 배열 (Character Arrays)

표준 라이브러리의 문자열 함수에게는 종료표시 (zero terminators) 가 매우 중요하다 .

int strlen(const char s[])

{

int i = 0;

while (s[i] != '\0')

i++;

return i;

}

RTDCS Lab.

문자 배열 (Character Arrays)

이 종료표시 문자를 빼먹는 것은 아주 자주 발생하는 오류이다 .

문자배열을 선언할때 배열 길이에 추가되는 공간 ("extra space") 을 좀 더 확실히 표현하는 것이 도움이 된다 .

const int MYSTRING_MAXLENGTH = 4;

char mystring[MYSTRING_MAXLENGTH + 1];

RTDCS Lab.

문자 배열 (append.cpp)

RTDCS Lab.

문자 배열 (append.cpp)

RTDCS Lab.

문자 배열 (append.cpp)

일반적으로 문자 배열을 사용하지 않는 것이 가장 좋은 방법이다 . string 클래스가 더 안전하고 편리하다 .

때때로 string 클래스가 생기기 이전에 만들어진 함수를 사용하는 경우처럼 문자열 (string) 을 문자배열로 변환해야 할 때가 있다 .

정수로 이루어진 문자 배열을 정수 값으로 변환시켜준다 .

int atoi(const char s[]) c_str 멤버 함수 c_str 이용하면 문자열 (string) 를

문자배열로 변환할수 있다 .

string year = "1999";

int y = atoi(year.c_str());

RTDCS Lab.

이차원 배열 (Two-Dimensional Arrays) 경우에 따라서는 숫자의 집합을 이차원으로 배치해야 할

때도 있다 . 이러한 배치를 값들의 행과 열이 있는 이차원 (two-

dimensional) 배열 (array) 또는 행렬 (matrix) 이라고 한다 .

C++ 에서는 이차원 배열에 저장하기 위해 두 개의 첨자(two subscripts) 가 있는 배열을 사용한다 .

const int BALANCE_ROWS = 11;

const int BALANCE_COLS = 6;

double balances[BALANCE_ROWS][BALANCE_COLS];

RTDCS Lab.

이차원 배열 (Two-Dimensional Arrays) 이 차원 배열에서 특정 원소에 값을 저장하려면 두 개의

대괄호로 행과 열을 표시해 주어야 한다 .

RTDCS Lab.

이차원 배열 (Two-Dimensional Arrays)

RTDCS Lab.

이차원 배열 (Two-Dimensional Arrays) 이차원 배열을 함수의 인자로 전달할 때는 열의 개수를 상수로 인자

타입과 함께 명시해야 한다 . 행의 개수는 변수일수도 있다 .

void print_table(const double table[][BALANCE_COLS], int table_rows)

{

const int WIDTH = 10;

cout << fixed << setprecision(2);

for (int i = 0; i < table_rows; i++) {

for (int j = 0; j < BALANCES_COLS; j++)

cout << setw(WIDTH) << table[i][j]; cout << "\n";

}

}

RTDCS Lab.

이차원 배열 (matrix.cpp)

RTDCS Lab.

이차원 배열 (matrix.cpp)

RTDCS Lab.

이차원 배열 (matrix.cpp)

top related