1. median()함수를 median.cpp( or median.c or median.C) 파일을 만들어서 따로 빼어보자
마찬가지로 median.h or median.hpp로 파일을 빼서 main()에서 include해야한다.
median.h
#ifndef HAHA_median_h #define HAHA_median_h #include <vector> double median(std::vector<double>); #endif
median.cpp
#include <algorithm> // sort함수 가져옴 #include <stdexcept> // domain_error 선언을 가져옴 #include <vector> // vector 타입의 선언을 가져옴 using namespace std; // vector<double> 타입의 가운데 값 구함 // 이함수를 호출함면 인수로 전달된 벡터 전체를 복사 double median(vector<double> vec) { typedef vector<double>::size_type vec_sz; vec_sz size = vec.size(); // 과제 점수의 유무 확인 if (size == 0) throw domain_error("median of an empty vector"); sort(vec.begin(), vec.end()); vec_sz mid = size / 2; return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid]; }
grade.h
#ifndef HAHA_grade_h #define HAHA_grade_h #include <vector> #include "student_info.h" using namespace std; double grade(double, double, double); double grade(double, double, const vector<double>&); double grade(const Student_info&); #endif
grade.cpp
#include <stdexcept> #include <vector> #include "grade.h" #include "median.h" #include "student_info.h" using namespace std; double grade(double midterm, double final, double homework) { return 0.2 * midterm + 0.4 * final + 0.4 * homework; } // 중간시험, 기말시험, 과제 점수의 벡터로 학생의 종합 점수를 구함 // 이 함수는 인수를 복사하지 않고 median 함수가 해당 작업을 진행 double grade(double midterm, double final, const vector<double>& hw) { if (hw.size() == 0) throw domain_error("과제 데이터가 없습니다."); return grade(midterm, final, median(hw)); } double grade(const Student_info& s) { return grade(s.midterm, s.final, s.homework); }
student_info.h
#ifndef HAHA_Student_info #define HAHA_Student_info #include <iostream> #include <string> #include <vector> using namespace std; struct Student_info { string name; double midterm, final; vector<double> homework; }; bool compare(const Student_info&, const Student_info&); istream& read(istream&, Student_info&); istream& read_hw(istream&, vector<double>&); #endif
student_info.cpp
// students 구조체와 관련된 함수들의 집합 #include "student_info.h" using std::istream; using std::vector; bool compare(const Student_info& x, const Student_info& y) { return x.name < y.name; } istream& read(istream& is, Student_info& s) { // 학생의 이름, 중간, 기말 시험 점수를 저장 is >> s.name >> s.midterm >> s.final; read_hw(is, s.homework); //학생의 모든 과제 점수를 읽어 저장 return is; } // 입력 스트림에서 과제 점수를 읽어서 vector<double>에 넣음 istream& read_hw(istream& in, vector<double>& hw) { if (in) { // 이전 내용을 제거 hw.clear(); // 과제 점수를 읽음 double x; while (in >> x) hw.push_back(x); // 다음 학생의 점수 입력 작업을 고려해 스트림을 지움 in.clear(); } return in; }
main.cpp
#include <algorithm> #include <iomanip> #include <ios> #include <iostream> #include <stdexcept> #include <string> #include <vector> #include "grade.h" #include "student_info.h" using namespace std; int main() { vector<Student_info> students; Student_info record; string::size_type maxlen = 0; // 가장 긴 이름의 길이 // 학생의 모든 데이터를 읽어 저장 // 불변성:students는 지금까지 읽은 모든 학생의 정보가 있음 // maxlen은 student에서 가장 긴 이름의 길이 while (read(cin, record)) { // 길이가 가장 긴 이름을 찾음 maxlen = max(maxlen, record.name.size()); students.push_back(record); } // 학생정보를 알파벳순으로 정렬 sort(students.begin(), students.end(), compare); // 이름과 점수를 출력 for (vector<Student_info>::size_type i = 0; i != students.size(); ++i) { // 이름과 오른쪽 공백을 포함하여 maxlen+1개의 문자를 출력 cout << students[i].name << string(maxlen + 1 - students[i].name.size(), ' '); // 점수를 계산하여 출력 try { double final_grade = grade(students[i]); streamsize prec = cout.precision(); cout << setprecision(3) << final_grade << setprecision(prec); } catch (domain_error e) { cout << e.what(); } cout << endl; } return 0; }
'PROGRAM > C++' 카테고리의 다른 글
열혈C++ CH06 (0) | 2021.03.09 |
---|---|
CH5. 문자열 분할 (0) | 2020.08.20 |
CH04. 프로그램 및 데이터 구조화 (0) | 2020.08.17 |
CH03. 데이터 일괄처리 (0) | 2020.08.17 |
Hello Johns! 출력하기 (0) | 2020.08.16 |