[Baekjoon] 백준 23629번 C++

방선생·2025년 6월 27일
0

Baekjoon

목록 보기
24/24

백준 23629번

사전 지식: 문자열 파싱, 해시 맵(unordered_map)


#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <cctype>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    string str_cal;
    cin >> str_cal;

    unordered_map<string,int> word2digit = {
        {"ZERO",0}, {"ONE",1}, {"TWO",2}, {"THREE",3}, {"FOUR",4},
        {"FIVE",5}, {"SIX",6}, {"SEVEN",7}, {"EIGHT",8}, {"NINE",9}
    };
    unordered_map<char,string> digit2word = {
        {'0',"ZERO"}, {'1',"ONE"}, {'2',"TWO"}, {'3',"THREE"}, {'4',"FOUR"},
        {'5',"FIVE"}, {'6',"SIX"}, {'7',"SEVEN"}, {'8',"EIGHT"}, {'9',"NINE"}
    };

    string num_cal;
    vector<char> ops;

    for (int i = 0; i < (int)str_cal.size(); i++) {
        if (str_cal[i] == '=') {
            num_cal.push_back('=');
            ops.push_back('=');
            break;
        }
        if (isupper(str_cal[i])) {
            string current;
            for (int len = 0; len < 5 && i < (int)str_cal.size() && isupper(str_cal[i]); len++) {
                current.push_back(str_cal[i++]);
                if (word2digit.count(current)) {
                    num_cal.push_back(char('0' + word2digit[current]));
                    current.clear();
                    break;
                }
            }
            i--;
            if (!current.empty()) {
                cout << "Madness!";
                return 0;
            }
        }
        else if (str_cal[i] == '+' || str_cal[i] == '-' || str_cal[i] == 'x' || str_cal[i] == '/') {
            num_cal.push_back(str_cal[i]);
            ops.push_back(str_cal[i]);
        }
        else {
            cout << "Madness!";
            return 0;
        }
    }

    vector<long long> nums;
    string numbuf;
    for (char c : num_cal) {
        if (isdigit(c)) {
            numbuf.push_back(c);
        } else {
            if (numbuf.empty()) {
                cout << "Madness!";
                return 0;
            }
            nums.push_back(stoll(numbuf));
            numbuf.clear();
            if (c == '=') break;
        }
    }

    int opCount = ops.size();
    if ((int)nums.size() != opCount) {
        cout << "Madness!";
        return 0;
    }

    long long result = nums[0];
    int idx = 0;
    for (char op : ops) {
        if (op == '=') break;
        long long b = nums[++idx];
        if (op == '+') result += b;
        else if (op == '-') result -= b;
        else if (op == 'x') result *= b;
        else if (op == '/') {
            if (b == 0) {
                cout << "Madness!";
                return 0;
            }
            result /= b;
        }
    }

    cout << num_cal << '\n';
    bool negative = (result < 0);
    if (negative) result = -result;
    string str_result = to_string(result);
    if (negative) cout << "-";
    for (char c : str_result) cout << digit2word[c];
    cout << '\n';

    return 0;
}

코드 설명

  1. 필요한 라이브러리 가져오기

  2. 문자열로된 계산식 입력

  3. 문자열 > 숫자로, 숫자 > 문자열로 변환하는 unordered_map 생성

  4. 반복문으로 문자열을 하나씩 입력 받음

  5. 문자열이 = 일경우 : 연산 이 끝났기 때문에 break

  6. 문자열이 영단어인 경우 : 하나씩 current에 입력 후 word2digit와 비교 > 단어가 완성될 경우 num_cal에 변환하여 입력

  7. 첫번째 for문이 시작될때 i++이 되기 때문에 문자열 하나를 건너뛰는 현상 발생함 > i - -;로 해결

  8. current가 비어있지 않다면 대응 되는 단어가 없었다는 것 > Madness 후 코드 종료

  9. 문자열이 사칙연산인 경우 : 연산자 모음(ops)에 저장

  10. 위에 세 경우가 아닌 경우 : 대응되지 않은 문자열이기 때문에 Madness 후 코드 종료

  11. num_cal에서 숫자를 하나씩 꺼내서 numbuf에 임시로 추가

  12. 연산자일 경우 nums에 그전까지 추가했던 numbuf를 longlong으로 변환후 추가

  13. 만약 연산자로 시작할 경우 계산이 안되기 때문에 Madness 후 코드 종료

  14. 숫자 연산자 숫자 =(연산자) 꼴이여야 하기 때문에 연산자와 숫자의 개수가 같아야함 (연산자 숫자 = 꼴일경우 계산이 안되기 때문) > 같이 않다면 Madness 후 코드 종료

  15. 연산 진행

  16. 최종 result를 다시 문자열 연산꼴로 변경 (result가 음수일 경우 - 추가)
profile
AI & Robotics

0개의 댓글