Upload
bernard-oneill
View
42
Download
0
Embed Size (px)
DESCRIPTION
Chapter 3. 일괄데이터로 작업하기 WORKING WITH BATCHES OF DATA. 3 장에서는 …. 1-2 장에서는 하나의 문자열을 읽어 들이고 그것을 출력하고 , 약간의 장식을 추가한 정도 대부분 문제는 이보다 훨씬 복잡하다 . 복잡해지는 원인은 여러 개의 유사한 데이터를 처리해야 하기 때문 3 장에서 다루는 문제는 , 학생의 시험성적과 과제성적을 읽어 들여 , 최종성적을 계산 (3.1 절 ) 입력된 성적을 저장해야 하는 경우 , vector 클래스 사용 (3.2 절 ) - PowerPoint PPT Presentation
Citation preview
일괄데이터로 작업하기WORKING WITH BATCHES OF DATA
Chapter 3
3 장에서는…
1-2 장에서는 하나의 문자열을 읽어 들이고 그것을 출력하고 , 약간의 장식을
추가한 정도 대부분 문제는 이보다 훨씬 복잡하다 .
복잡해지는 원인은 여러 개의 유사한 데이터를 처리해야 하기 때문
3 장에서 다루는 문제는 , 학생의 시험성적과 과제성적을 읽어 들여 , 최종성적을 계산 (3.1
절 ) 입력된 성적을 저장해야 하는 경우 , vector 클래스 사용 (3.2 절 )
일련의 데이터를 처리하는 다양한 방법 얼마나 많은 성적들이 있는지 미리 알지 못해도 , 저장할 수 있는
방법 2
3.1 학생 성적 계산하기
기말 40% 중간 20% 과제의 평균이 40% 일 때 최종 성적 계산하는 과정
1) 이름 읽어 들이기2) 중간고사와 기말고사 성적 읽어 들이기3) 과제성적 읽어 들이기
몇 개를 과제점수를 읽어 들였는지 저장 현재까지 읽어 들인 과제 점수의 합계 저장
4) 과제성적 평균 계산하기 5) 최종 성적 계산하기
최종 = 중간 * 0.2 + 기말 * 0.4 + 과제 평균 * 0.4
3
학생 성적 계산 – 과제성적 평균
4
#include <iomanip>#include <ios>#include <iostream>#include <string>
using namespace std; // using std::setprecision; using std::streamsize;
int main(){
// ask for and read the student's namecout << "Please enter your first name: ";string name;cin >> name;cout << "Hello, " << name << "!" << endl;
// ask for and read the midterm and final gradescout << "Please enter your midterm and final exam grades: ";double midterm, final;cin >> midterm >> final;
5
// ask for the homework gradescout << "Enter all your homework grades, " "followed by end-of-file: ";
// the number and sum of grades read so farint count = 0;double sum = 0;
// a variable into which to readdouble x;
// invariant: we have read `count' grades so far, and// `sum' is the sum of the first `count' gradeswhile (cin >> x) {
++count;sum += x;
}
// write the resultstreamsize prec = cout.precision();cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * sum / count << setprecision(prec) << endl;
return 0;}
성적 읽어 들이기
cout <<“Enter your midterm and final …: ”;double midterm, final;cin >> midterm >> final;
실수형 float ( 단일 정밀도 부동소수점 타입 ): 6 자리 유효 숫자 double (double-precision floating point): 최소 10 자리 유효
숫자 부동소수점 연산에는 항상 double 을 써라 .
보다 정확하고 , 하드웨어 발전으로 속도도 느리지 않다 .
입력 연산자 >> 읽어 들인 후 , 왼쪽 연산자를 결과 값으로 리턴함 cin>>midterm>>final; // cin>>midterm;
// cin>>final;
6
문자열 리터럴
cout << "Enter all your homework grades, "
"followed by end-of-file: ";
공백문자만으로 구분된 둘 또는 그 이상의 문자열 리터럴은 자동적으로 합쳐진다
7
cout << "Enter all your homework grades, followed by end-of-file: ";
초기화 하기
int count=0;double sum=0; // 자동으로 형 변환 일어남 : sum=0.0;
명시적으로 초기화하지 않으면 ,
기본 타입의 지역 변수들은 정의되지 않은 (undefined) 상태 쓰레기 값을 가지므로 , 이 상태로 사용하면 위험 초래
클래스 타입의 변수는 디폴트 초기화 (default-initialization)
예 , string 타입 변수는 빈 문자열로 초기화 됨
초기화 할지 말지 어떻게 판단 ? 프로그래머의 책임 위 프로그램에서 , 왜 name 과 x 는 초기화 안하지 ?
왜 count 와 sum 은 초기화 하지 ?
8
입력의 끝 테스트하기// 불변식 : 지금까지 count 개의 성적을 읽어 들였고// sum 은 처음 count 개의 성적의 합이다 .while ( cin>>x ) { ++count; sum += x;}
while 문의 condition 에 cin>>x 등장 가장 최근의 입력 요청 ( 즉 , cin >> x ) 이 성공하면 , 조건식이 성공 cin>>x 에서 >> 연산자는 왼쪽 피연산자 cin 을 리턴하는데 , cin
값은 true/false 로 자동 변환 아래 경우에 cin>> x 가 false 가 됨 ( 보다 구체적인 원리는 12.5
절 ) 파일 끝 입력 ( 키보드에서 Ctrl-Z 또는 Ctrl-D) 변수 형과 호환되지 않는 값 입력 . 예 ) int 형 입력에 숫자외 입력 입력장치에 대한 하드웨어 오류 감지
9
출력에서 정밀도 정해주기 streamsize prec = cout.precision();cout << "Your final grade is " << setprecision(3) << 0.2*midterm + 0.4*final + 0.4*sum / count << setprecision(prec) << endl;
setprecision(3) 주요 자리수 세자리 출력 : 소수점 앞에 두 자리 , 뒤에 한 자리
출력 후 cout 의 정밀도를 바꾸기 이전 상태로 돌려주기 정밀도 바꾸기 이전 상태 보관 : streamsize prec = cout.precision();
정밀도를 바꾸기 이전 상태로 돌려주기 : setprecision(prec);
10
3.2 평균 대신 중앙 값 사용하기
중앙값 (median) 과 평균값 (average) 입력이 55 80 12 70 65 라면 ,
평균값 : (55+80+12+70+65)/5=56.4 중앙값 : 65
중앙값은 어떻게 구할까 ? Sorting( 오름차순 또는 내림차순 ) 후 가운데 있는 값을 취함 입력 값들의 개수가 짝수이면 : 가운데 두 개의 평균
중앙값을 사용하기로 한다면 프로그램은 ? 앞의 프로그램처럼 , 읽은 값을 저장하지 않아도 될까 ? 저장해야 한다면 어디에 어떻게 ?
중앙값을 계산하기 위해 값을 한번에 하나씩 읽어 저장 , 끝까지 다 읽은 후에 값들을
정렬 , 중간에 위치한 값 ( 들 ) 을 구함
11
vector 에 일련의 데이터 저장
표준 라이브러리는 vector 타입을 제공 vector 타입은 주어진 타입에 대한 여러 개의 값들을 저장 필요한 때에 크기가 커지며 , 개별 값들을 효과적으로 접근
가능
vector 타입의 객체에 저장하기
12
double x;vector<double> homework;
while (cin>>x) homework.push_back(x);
// 이전 것과 비교해보자 .int count=0;double sum=0;double x;
while(cin>>x) { ++count; sum+=x;}
vector 타입vector<double> homework;homework.push_back(x);
vector 는 일련의 값을 저장하는 컨테이너 (container) 값을 여러 개 저장할 수 있는 타입을 컨테이너라 한다 . vector 타입은 템플릿 클래스 (template class) 로 정의되어 있음
‘ 객체’의 타입이 매개변수화 되어 있음 . <> 안에 명시 vector<double> 은 double 타입의 객체를 담는다 vector<string> 은 string 타입의 객체를 담는다
push_back(x) 멤버 함수 vector 의 끝에 새로운 요소를 추가하는 함수
즉 , vector 의 뒤 (back) 에 밀어 넣음 (push) 자연히 vector 의 크기는 하나 증가됨 몇 개의 요소를 담고 있는지는 어떻게 알지 ? vector 의 효율 : 요소가 많아지면 효율이 떨어지나 ?
13
템플릿 클래스를 정의하는 방법은 11
장에서 !!
vector 크기
vector<double>::size_type size = homework.size();
vector 크기 알아내기 size() 라는 멤버함수 사용 . homework.size();
vector 의 크기를 저장할 변수 vector 의 size_type 을 사용 . vector<double>::size_type
size;
typedef 은 해당 타입에 대한 동의어를 정의
typedef vector<double>::size_type vec_szvec_sz size = homework.size();
typedef 에 의해 size_type 과 vec_sz 는 동의어가 됨 size_type 을 여러 군데에서 사용하는 경우 유용함
14
오류 처리
오류 처리는 매우 중요하다 .“ 어제까지는 됐는데…”“ 컴퓨터가 이상하네 . 되다 안되다 하네 .”
모든 입력 사례 (instance) 를 고려해라 !
현재 문제에서는 , size 가 0 일 경우와 그렇지 않은 경우
if(size==0) { cout << endl <<“You must enter your grades, ” “Please try again.” << endl;
return 1;} 운영체제에게 1 을 리턴 하여 실행 실패를 알림 main 이 0 을 리턴하면 프로그램이 성공했다고 가정함 오류 처리를 해주지 않으면 어떤 일이 생길까 ?
15
정렬하기
sort(homework.begin(), homework.end());
sort() 함수 컨테이너에 들어있는 값들을 오름차순 (nondecreasing) 으로
정렬 정렬된 결과를 담을 새 컨테이너를 생성하는 것이 아니라 , 원래
컨테이너의 요소들의 값을 서로 바꿈 효율 : n log(n) 알고리즘 사용 . C++ 의 표준 라이브러리는 꽤 효율적이다
begin() 과 end() 는 vector 의 멤버 함수 homework.begin() 는 첫번째 요소 , homework.end() 는
마지막 요소를 나타냄 . homework 의 첫 번째와 마지막 요소는 homework[0] 과 homework[size-1]
16
중앙값 찾기 vec_sz mid = size/2;double median;median = size%2==0?(homework[mid]+homework[mid-1])/2: homework[mid];
나머지 연산자 %, 조건부 연산자 ?:
size 가 짝수일 때 ,
size 가 홀수일 때 ,
17
// 홀수 개 일 때
// 짝수 개 일 때
학생 성적 계산 – 과제성적 중앙값
18
#include <algorithm>#include <iomanip>#include <ios>#include <iostream>#include <string>#include <vector>
using namespace std;int main(){ // ask for and read the student's name cout << "Please enter your first name: "; string name; cin >> name; cout << "Hello, " << name << "!" << endl;
// ask for and read the midterm and final grades cout << "Please enter your midterm and final exam grades:"; double midterm, final; cin >> midterm >> final;
// ask for and read the homework grades cout << "Enter all your homework grades, “ "followed by end-of-file: “;
19
vector<double> homework;double x;// invariant: `homework' contains all the homework grades read
so farwhile (cin >> x)
homework.push_back(x);
// check that the student entered some homework gradestypedef vector<double>::size_type vec_sz;vec_sz size = homework.size();if (size == 0) {
cout << endl << "You must enter your grades. Please try again." << endl; return 1;
}
// sort the gradessort(homework.begin(), homework.end());
// compute the median homework gradevec_sz mid = size/2;double median;median = size%2==0 ? (homework[mid] + homework[mid-
1])/2 : homework[mid];
// compute and write the final gradestreamsize prec = cout.precision();cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * median << setprecision(prec) << endl;
return 0;}
벡터의 원소 접근하기
vector<int> v;v.push_back(100); // 100v.push_back(10); // 100 10v.push_back(1); // 100 10 1
cout << v[0] << endl; // prints 100cout << v[1] << endl; // prints 10cout << v[2] << end; // prints 1cout << v[3] << endl; // ERROR! No element at this
position.
for(unsigned int i=0; i != v.size(); ++i){cout << v[i] << endl;
}
20
출력 : 소수점 3자리 지정
소수점 3자리까지 출력하는 방법cout.setf(ios::fixed, ios::floatfield); cout.precision(3);
21
벡터 초기화 정수형의 빈 벡터 (empty vector) 생성
vector<int> a;
100 개의 double 형 벡터 생성 , 각 요소의 초기값은 3.14 로 설정int n = 100;vector<double> b( 100, 3.14 );
10,000 개의 정수를 저장하는 벡터 생성vector<int> c( n*n );
벡터 b 를 복사한 벡터 d 생성vector<double> d( b );vector<double> e( b ); // ERROR; e 는 double 형 , b는 int 형
22
cout << a.size() << endl << b.size() << endl << c.size() << endl << d.size() << endl;