본문 바로가기

PROGRAM/C++

CH04. 프로그램 및 데이터 구조화

1. Grade 함수로 구현하기

double grade(double midterm, double final, double homework)
{
	return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}

 

2. median 함수로 구현하기

// 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];
}

 

3. grade()와 median() 함수를 코드에 적용하기

#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

double grade(double midterm, double final, double homework)
{
	return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}

// 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];
}


int main()
{
	// 학생의 이름을 묻고 입력받음
	cout << "이름을 입력하세요: ";
	string name;
	cin >> name;
	cout << "Hello, " << name << "!" << endl;

	// 중간시험과 기말시험의 점수를 묻고 입력받음
	cout << "중간, 기말 시험 점수 입력(예 69.0 79.0): ";
	double midterm, final;
	cin >> midterm >> final;

	// 과제 점수를 물음
	cout << "과제 점수 입력, ""마지막에 EOF(end-of-file)입력 : ";
	vector<double> homework;
	double x;
	// 불변성: homework는 지금까지 입력받은 과제 점수가 있음
	while (cin >> x)
		homework.push_back(x);

	double median_value = median(homework);
	
	// 결과 출력
	double result = grade(midterm, final, median_value);
	streamsize prec = cout.precision();
	cout << "당신의 최종 점수는 \n"
		<< setprecision(3) << result << '\n' 	// 총 세자리 정밀도
		<< fixed << setprecision(3) << result << '\n'	//소수점 아래 3자리
		<< fixed << setprecision(prec) << result << '\n'//C++ 기본 6자리
		<< setprecision(prec) << '\n'; // 후속 출력 정밀도를 초기화
	return 0;
}

 

4. grade()함수를 수정하여 meian()함수 포함시키기

#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using namespace std;
double grade(double midterm, double final, double homework);
double median(vector<double> vec);
double grade(double midterm, double final, const vector<double>& hw);

int main()
{
	// 학생의 이름을 묻고 입력받음
	cout << "이름을 입력하세요: ";
	string name;
	cin >> name;
	cout << "Hello, " << name << "!" << endl;

	// 중간시험과 기말시험의 점수를 묻고 입력받음
	cout << "중간, 기말 시험 점수 입력(예 69.0 79.0): ";
	double midterm, final;
	cin >> midterm >> final;

	// 과제 점수를 물음
	cout << "과제 점수 입력, ""마지막에 EOF(end-of-file)입력 : ";
	vector<double> homework;
	double x;
	// 불변성: homework는 지금까지 입력받은 과제 점수가 있음
	while (cin >> x)
		homework.push_back(x);

	// 결과 출력
	double result = grade(midterm, final, homework);
	streamsize prec = cout.precision();
	cout << "당신의 최종 점수는 \n"
		<< setprecision(3) << result << '\n' 	// 총 세자리 정밀도
		<< fixed << setprecision(3) << result << '\n'	//소수점 아래 3자리
		<< fixed << setprecision(prec) << result << '\n'//C++ 기본 6자리
		<< setprecision(prec) << '\n'; // 후속 출력 정밀도를 초기화
	return 0;
}


// 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];
}

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

 

 

5. 과제 (homework) 자료 입력하기를 함수로 지정하기

// 입력 스트림에서 과제 점수를 읽어서 vector<double>에 넣음
istream& read_homework(istream& in, vector<double>& homework)
{
    if (in) {
        //이전 내용 삭제
        homework.clear();

        //과제 점수 읽기
        double x;
        // 불변성: homework는 지금까지 입력받은 과제 점수가 있음
        while (in >> x)
            homework.push_back(x);

        in.clear();
    }

    return in;
}

 

#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using namespace std;
double grade(double midterm, double final, double homework);
double median(vector<double> vec);
double grade(double midterm, double final, const vector<double>& hw);
istream& read_homework(istream& in, vector<double>& homework);

int main()
{
	// 학생의 이름을 묻고 입력받음
	cout << "이름을 입력하세요: ";
	string name;
	cin >> name;
	cout << "Hello, " << name << "!" << endl;

	// 중간시험과 기말시험의 점수를 묻고 입력받음
	cout << "중간, 기말 시험 점수 입력(예 69.0 79.0): ";
	double midterm, final;
	cin >> midterm >> final;

	// 과제 점수를 물음
	cout << "과제 점수 입력, ""마지막에 EOF(end-of-file)입력 : ";
	
	// 과제 자료 읽어오기
	vector<double> homework;
	read_homework(cin, homework);
	// compute and generate the final grade, if possible
	try {
		double final_grade = grade(midterm, final, homework);
		streamsize prec = cout.precision();
		cout << "당신의 최종 점수는 \n"
			<< fixed << setprecision(3) << final_grade << '\n'	//소수점 아래 3자리
			<< setprecision(prec) << '\n'; // 후속 출력 정밀도를 초기화
	}
	catch (domain_error) {
		cout << endl << "점수를 다시 입력하세요" << endl;
		return 1;
	}

	return 0;
}


// 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];
}

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

// 입력 스트림에서 과제 점수를 읽어서 vector<double>에 넣음
istream& read_homework(istream& in, vector<double>& homework)
{
    if (in) {
        //이전 내용 삭제
        homework.clear();

        //과제 점수 읽기
        double x;
        // 불변성: homework는 지금까지 입력받은 과제 점수가 있음
        while (in >> x)
            homework.push_back(x);

        in.clear();
    }
    return in;
}

- 구조체로 학생 데이터 통합하기

struct Student_info{
	string name;
	double midterm, final;
	vector<double> homework;
}; //마지막에 세미콜론 붙여야함

-학생의 정보를 구조체로 입력받기

istream& read(istream& is, Student_info& s)
{
	// 학생의 이름, 중간, 기말 시험 점수를 저장
	is >> s.name >> s.midterm >> s.final;
	read_homework(is, s.homework); //학생의 모든 과제 점수를 읽어 저장
	return is;
}

- Student_info를 입력으로 하는 grade 함수의 overloading 

double grade(const Student_info& s)
{
	return grade(s.midterm, s.final, s.homework);
}

 - sort함수를 Student_info구조체에 사용하기 위해서는 마지막에 서술함수를 적용하여 사용할수있다.

bool compare(const Student_info& x, const Student_info& y)
{
	return x.name < y.name;
}

-합쳐진 코드

#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Student_info
{
    string name;
    double midterm, finalterm;
    vector<double> homework;
};

double grade(double midterm, double finalterm, double homework);
double grade(double midterm, double finalterm, const vector<double>& hw);
double grade(const Student_info& s);
double median(vector<double> vec);
istream& read_homework(istream& in, vector<double>& homework);
istream& read(istream& is, Student_info& s);
bool compare(const Student_info& x, const Student_info& y);

int main()
{
    vector<Student_info> students;
    Student_info record;
    string::size_type maxlen = 0;

    while (read(cin, record)) {
        maxlen = max(maxlen, record.name.size());
        students.push_back(record);
    }

    sort(students.begin(), students.end(), compare);

    cout << endl;
    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 << "당신의 최종 점수는 : "
                << fixed << setprecision(3) << final_grade
                << setprecision(prec); 
        }
        catch(domain_error e){
            cout << e.what();
        }
        cout << endl;
    }

    return 0;
}


double grade(double midterm, double finalterm, double homework) {
    return 0.2 * midterm + 0.4 * finalterm + 0.4 * homework;
}

double grade(double midterm, double finalterm, const vector<double>& hw) {
    if (hw.size() == 0)
        throw domain_error("과제 데이터가 없습니다.");

    return grade(midterm, finalterm, median(hw));
}

double grade(const Student_info&s) {
    return grade(s.midterm,s.finalterm, s.homework);
}


double median(vector<double> vec) {
    // 과제 점수의 유무 확인
    typedef vector<double>::size_type vec_sz;
    vec_sz size = vec.size();
    if (size == 0) {
        throw domain_error("벡터가 비었습니다.");
    }
    // 점수를 정렬
    sort(vec.begin(), vec.end());
    // 과제 점수의 가운데값(median) 구함
    vec_sz mid = size / 2;
    double output = size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
    return output;
}

istream& read_homework(istream& in, vector<double>& homework)
{
    if (in) {
        //이전 내용 삭제
        homework.clear();

        //과제 점수 읽기
        double x;
        // 불변성: homework는 지금까지 입력받은 과제 점수가 있음
        while (in >> x)
            homework.push_back(x);

        in.clear();
    }

    return in;

}

istream& read(istream& is, Student_info& s)
{
    is >> s.name >> s.midterm >> s.finalterm;
    read_homework(is, s.homework);
    return is;
}

bool compare(const Student_info& x, const Student_info& y)
{
    return x.name < y.name;
}

'PROGRAM > C++' 카테고리의 다른 글

CH5. 문자열 분할  (0) 2020.08.20
4. 프로그램 및 데이터 구조화 -2  (0) 2020.08.18
CH03. 데이터 일괄처리  (0) 2020.08.17
Hello Johns! 출력하기  (0) 2020.08.16
입력한숫자만큼 별 출력하기(4자리수 한정)  (0) 2020.08.12