문제 설명

인하대학교 컴퓨터공학과를 졸업하기 위해서는, 전공평점이 3.3 이상이거나 졸업고사를 통과해야 한다. 그런데 아뿔싸, 치훈이는 깜빡하고 졸업고사를 응시하지 않았다는 사실을 깨달았다!

치훈이의 전공평점을 계산해주는 프로그램을 작성해보자.

전공평점은 전공과목별 (학점 × 과목평점)의 합을 학점의 총합으로 나눈 값이다.

인하대학교 컴퓨터공학과의 등급에 따른 과목평점은 다음 표와 같다.

A+ 4.5
A0 4.0
B+ 3.5
B0 3.0
C+ 2.5
C0 2.0
D+ 1.5
D0 1.0
F 0.0

P/F 과목의 경우 등급이 P또는 F로 표시되는데, 등급이 P인 과목은 계산에서 제외해야 한다.

과연 치훈이는 무사히 졸업할 수 있을까?

입력

20줄에 걸쳐 치훈이가 수강한 전공과목의 과목명, 학점, 등급이 공백으로 구분되어 주어진다.

출력

입력으로 주어진 단어가 몇 개의 크로아티아 알파벳으로 이루어져 있는지 출력한다.

제한

  • 1 ≤ 과목명의 길이 ≤ 50
  • 과목명은 알파벳 대소문자 또는 숫자로만 이루어져 있으며, 띄어쓰기 없이 주어진다. 입력으로 주어지는 모든 과목명은 서로 다르다.
  • 학점은 1.0, 2.0, 3.0, 4.0중 하나이다.
  • 등급은 A+, A0, B+, B0, C+, C0, D+, D0, F, P중 하나이다.
  • 적어도 한 과목은 등급이 P가 아님이 보장된다.

입출력 예

입력1 출력1
ObjectOrientedProgramming1 3.0 A+ 3.284483
IntroductiontoComputerEngineering 3.0 A+  
ObjectOrientedProgramming2 3.0 A0  
CreativeComputerEngineeringDesign 3.0 A+  
AssemblyLanguage 3.0 A+  
InternetProgramming 3.0 B0  
ApplicationProgramminginJava 3.0 A0  
SystemProgramming 3.0 B0  
OperatingSystem 3.0 B0  
WirelessCommunicationsandNetworking 3.0 C+  
LogicCircuits 3.0 B0  
DataStructure 4.0 A+  
MicroprocessorApplication 3.0 B+  
EmbeddedSoftware 3.0 C0  
ComputerSecurity 3.0 D+  
Database 3.0 C+  
Algorithm 3.0 B0  
CapstoneDesigninCSE 3.0 B+  
CompilerDesign 3.0 D0  
ProblemSolving 4.0 P  
입력2 출력2
BruteForce 3.0 F 0.000000
Greedy 1.0 F  
DivideandConquer 2.0 F  
DynamicProgramming 3.0 F  
DepthFirstSearch 4.0 F  
BreadthFirstSearch 3.0 F  
ShortestPath 4.0 F  
DisjointSet 2.0 F  
MinimumSpanningTree 2.0 F  
TopologicalSorting 1.0 F  
LeastCommonAncestor 2.0 F  
SegmentTree 4.0 F  
EulerTourTechnique 3.0 F  
StronglyConnectedComponent 2.0 F  
BipartiteMatching 2.0 F  
MaximumFlowProblem 3.0 F  
SuffixArray 1.0 F  
HeavyLightDecomposition 4.0 F  
CentroidDecomposition 3.0 F  
SplayTree 1.0 F  

코드 구현

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <map>

using namespace std;
int main(){
    map<string, double> orderedMap;
    orderedMap["A+"] = 4.5;
    orderedMap["A0"] = 4.0;
    orderedMap["B+"] = 3.5;
    orderedMap["B0"] = 3.0;
    orderedMap["C+"] = 2.5;
    orderedMap["C0"] = 2.0;
    orderedMap["D+"] = 1.5;
    orderedMap["D0"] = 1.0;
    orderedMap["F"] = 0.0;

    double average=0;
    int totalSub=0;
    for(int i=0; i<20; i++){
        vector<string> score;
        string input;
        getline(cin, input);

        stringstream ss(input); //stringstream 객체로 초기화
        string temp;
        while(ss>>temp){ //ss에서 공백을 기준으로 단어 추출 후 벡터에 저장
            score.push_back(temp); //temp=DataStructure, temp=4.0, temp=A+
        }

        auto it = orderedMap.find(score[2]);
        if(it != orderedMap.end()){
            average += stoi(score[1])*(it->second);
            totalSub += stoi(score[1]);
        }
        else if(score[2] == "P"){
        }
        else{
            cout << "invalid grade" << endl;
        }
    }

    cout << average/totalSub << endl;
}

공부한 내용

stringstream

  • <sstream>헤더에 정의되어 있다.
  • 문자열을 입력받아 데이터를 추출, 추가하거나 형식을 변환할 수 있다.
  • 공백이나 다른 구분자를 기준으로 토큰으로 분할하여 데이터를 추출할 수 있다.

코드 예시1

string input = "Hello, World! My name is Tom.";

stringstream ss(input);
string token;
while(ss>>token){
    cout << token << endl; // "Hello," "World!" "My" "name" "is" "Tom."
}
코드 예시1 출력

ex1_result

코드 예시2

string input = "ObjectOrientedProgramming1 3.0 A+";

stringstream ss(input);
string token;
while(ss>>token){
    cout << token << endl; 
}
코드 예시2 출력

ex1_result

코드 예시3 - 문자열에서 숫자 추출

string input = "ObjectOrientedProgramming1 3.5 A+";
vector<string> vec;

stringstream ss(input);
string token;
while(ss>>token){
    vec.push_back(token);
}
double grade = stod(vec[1]);
cout << grade << endl; //3.5
코드 예시3 출력

ex1_result

Review

최근에 정리한 [C++] map vs unordered_map을 사용해서 문제를 풀어봤다.


출처: 백준, https://www.acmicpc.net/problem/25206