1 / 22

일괄데이터로 작업하기 WORKING WITH BATCHES OF DATA

Chapter 3. 일괄데이터로 작업하기 WORKING WITH BATCHES OF DATA. 3 장에서는 …. 1-2 장에서는 하나의 문자열을 읽어 들이고 그것을 출력하고 , 약간의 장식을 추가한 정도 대부분 문제는 이보다 훨씬 복잡하다 . 복잡해지는 원인은 여러 개의 유사한 데이터를 처리해야 하기 때문 3 장에서 다루는 문제는 , 학생의 시험성적과 과제성적을 읽어 들여 , 최종성적을 계산 (3.1 절 ) 입력된 성적을 저장해야 하는 경우 , vector 클래스 사용 (3.2 절 )

Download Presentation

일괄데이터로 작업하기 WORKING WITH BATCHES OF DATA

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 3 일괄데이터로 작업하기WORKING WITH BATCHES OF DATA

  2. 3 장에서는… • 1-2 장에서는 • 하나의 문자열을 읽어 들이고그것을 출력하고, 약간의 장식을 추가한 정도 • 대부분 문제는 이보다 훨씬 복잡하다. • 복잡해지는 원인은 여러 개의 유사한 데이터를 처리해야 하기 때문 • 3 장에서 다루는 문제는, • 학생의 시험성적과 과제성적을 읽어 들여, 최종성적을 계산(3.1절) • 입력된 성적을 저장해야 하는 경우, vector 클래스 사용 (3.2절) • 일련의 데이터를 처리하는 다양한 방법 • 얼마나 많은 성적들이 있는지 미리 알지 못해도, 저장할 수 있는 방법

  3. 3.1 학생 성적 계산하기 • 기말 40% 중간 20% 과제의 평균이 40% 일 때 최종 성적 계산하는 과정 1) 이름 읽어 들이기 2) 중간고사와 기말고사 성적 읽어 들이기 3) 과제성적 읽어 들이기 • 몇 개를 과제점수를 읽어 들였는지 저장 • 현재까지 읽어 들인 과제 점수의 합계 저장 4) 과제성적 평균 계산하기 5) 최종 성적 계산하기 • 최종 = 중간 * 0.2 + 기말 * 0.4 + 과제 평균 * 0.4

  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 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;

  5. // ask for the homework grades cout << "Enter all your homework grades, " "followed by end-of-file: "; // the number and sum of grades read so far int count = 0; double sum = 0; // a variable into which to read double x; // invariant: we have read `count' grades so far, and // `sum' is the sum of the first `count' grades while (cin >> x) { ++count; sum += x; } // write the result streamsize 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; }

  6. 성적 읽어 들이기 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;

  7. 문자열 리터럴 cout << "Enter all your homework grades, " "followed by end-of-file: "; • 공백문자만으로 구분된 둘 또는 그 이상의 문자열 리터럴은 자동적으로 합쳐진다 cout << "Enter all your homework grades, followed by end-of-file: ";

  8. 초기화 하기 int count=0; double sum=0; // 자동으로 형 변환 일어남: sum=0.0; • 명시적으로 초기화하지 않으면, • 기본 타입의 지역 변수들은 정의되지 않은(undefined)상태 • 쓰레기 값을 가지므로, 이 상태로 사용하면 위험 초래 • 클래스 타입의 변수는 디폴트 초기화(default-initialization) • 예, string 타입 변수는 빈 문자열로 초기화 됨 • 초기화 할지 말지 어떻게 판단? • 프로그래머의 책임 • 위 프로그램에서, 왜 name과 x는 초기화 안하지? 왜 count와 sum은 초기화 하지?

  9. 입력의 끝 테스트하기 // 불변식: 지금까지 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형 입력에 숫자외 입력 • 입력장치에 대한 하드웨어 오류 감지

  10. 출력에서 정밀도 정해주기 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);

  11. 3.2 평균 대신 중앙 값 사용하기 • 중앙값(median)과 평균값(average) • 입력이 55 80 12 70 65 라면, • 평균값:(55+80+12+70+65)/5=56.4 • 중앙값:65 • 중앙값은 어떻게 구할까? • Sorting(오름차순 또는 내림차순)후 가운데 있는 값을 취함 • 입력 값들의 개수가 짝수이면: 가운데 두 개의 평균 • 중앙값을 사용하기로 한다면 프로그램은? • 앞의 프로그램처럼, 읽은 값을 저장하지 않아도 될까? • 저장해야 한다면 어디에 어떻게? • 중앙값을 계산하기 위해 • 값을 한번에 하나씩 읽어 저장, 끝까지 다 읽은 후에 값들을 정렬, 중간에 위치한 값(들)을 구함

  12. vector에 일련의 데이터 저장 • 표준 라이브러리는 vector 타입을 제공 • vector 타입은 주어진 타입에 대한 여러 개의 값들을 저장 • 필요한 때에 크기가 커지며, 개별 값들을 효과적으로 접근 가능 • vector 타입의 객체에 저장하기 // 이전 것과 비교해보자. int count=0; double sum=0; double x; while(cin>>x) { ++count; sum+=x; } double x; vector<double> homework; while (cin>>x) homework.push_back(x);

  13. 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의 효율:요소가많아지면 효율이 떨어지나? • 템플릿 클래스를 정의하는 방법은 11장에서!!

  14. 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_sz vec_sz size = homework.size(); • typedef에 의해 size_type과 vec_sz는 동의어가 됨 • size_type을 여러 군데에서 사용하는 경우유용함

  15. 오류 처리 • 오류 처리는 매우 중요하다. “어제까지는 됐는데…” “컴퓨터가 이상하네. 되다 안되다 하네.” • 모든 입력 사례(instance)를 고려해라! • 현재 문제에서는, size가 0일 경우와그렇지 않은 경우 if(size==0) { cout << endl <<“You must enter your grades, ” “Please try again.” << endl; return 1; } • 운영체제에게 1을 리턴 하여 실행 실패를 알림 • main이 0을 리턴하면 프로그램이 성공했다고 가정함 • 오류 처리를 해주지 않으면 어떤 일이 생길까?

  16. 정렬하기 sort(homework.begin(), homework.end()); • sort() 함수 • 컨테이너에 들어있는 값들을 오름차순(nondecreasing)으로 정렬 • 정렬된 결과를 담을 새 컨테이너를 생성하는 것이 아니라, 원래 컨테이너의 요소들의 값을 서로 바꿈 • 효율: n log(n)알고리즘 사용. • C++의 표준 라이브러리는 꽤 효율적이다 • begin()과 end()는 vector의 멤버 함수 • homework.begin()는 첫번째 요소, homework.end()는 마지막 요소를 나타냄. • homework의 첫 번째와 마지막 요소는 homework[0]과 homework[size-1]

  17. 중앙값 찾기 vec_sz mid = size/2; double median; median = size%2==0?(homework[mid]+homework[mid-1])/2: homework[mid]; 나머지 연산자 %, 조건부 연산자 ?: • size가 짝수일 때, • size가 홀수일 때, // 홀수 개 일 때 // 짝수 개 일 때

  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 far while (cin >> x) homework.push_back(x); // check that the student entered some homework grades typedef 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 grades sort(homework.begin(), homework.end()); // compute the median homework grade vec_sz mid = size/2; double median; median = size%2==0 ? (homework[mid] + homework[mid-1])/2 : homework[mid]; // compute and write the final grade streamsize prec = cout.precision(); cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * median << setprecision(prec) << endl; return 0; }

  20. 벡터의 원소 접근하기 vector<int> v; v.push_back(100); // 100 v.push_back(10); // 100 10 v.push_back(1); // 100 10 1 cout << v[0] << endl; // prints 100 cout << v[1] << endl; // prints 10 cout << v[2] << end; // prints 1 cout << v[3] << endl; // ERROR! No element at this position. for(unsigned int i=0; i != v.size(); ++i){ cout << v[i] << endl; }

  21. 출력: 소수점 3자리 지정 • 소수점 3자리까지 출력하는 방법 cout.setf(ios::fixed, ios::floatfield); cout.precision(3);

  22. 벡터 초기화 • 정수형의 빈 벡터(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형 cout << a.size() << endl << b.size() << endl << c.size() << endl << d.size() << endl;

More Related