본문 바로가기

PROGRAM/C++

4. 프로그램 및 데이터 구조화 -2

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