본문 바로가기

코딩테스트 공부

입력값 처리(숫자 반올림, 올림, 내림, 문자열 스트림, 진법 변환)

이 글에서 사용하는 연산들은 모두 cmath 헤더를 포함해야 한다.

반올림(round)

주어진 숫자를 가장 가까운 정수로 변환하는 것. round 함수를 사용한다.

0.5인 경우 0에서 먼 쪽(그냥 절댓값 기준 큰 수라고 이해하면 될 듯)으로 반올림한다.

ex) round(2.5) = 3, round(-2.5) = -3

// 목적: C++에서 round 함수를 사용하여 소수점 숫자를 가장 가까운 정수로 반올림하는 예제
// 동작: 소수점이 0.5 이상이면 올림, 아니면 내림

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    double num1 = 3.2;
    double num2 = 3.5;
    double num3 = 3.8;

    cout << round(num1) << endl; // 3
    cout << round(num2) << endl; // 4
    cout << round(num3) << endl; // 4

    return 0;
}

올림(ceil = 천장)

주어진 숫자보다 크거나 같은 정수 중 가장 작은 값을 구한다.

// 목적: C++에서 ceil 함수를 사용하여 주어진 수를 올림 처리하는 예제
// 동작: 실수 값을 올림하여 크거나 같은 가장 작은 정수로 변환

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double a = 3.2;
    double b = -3.2;

    cout << ceil(a) << endl; // 4
    cout << ceil(b) << endl; // -3

    return 0;
}

소수점 버리기 / 내림(floor = 바닥)

주어진 수를 가장 가까운 작은 정수로 변환한다.

주의해야 할 점은 음수에 대해서는 소수점을 버리는 것이 아니라 숫자가 더 줄어든다.

ex) floor(-3.7) = -4

// 목적: C++에서 floor 함수를 사용하여 주어진 수를 내림 처리하는 예제
// 동작: 실수 값을 내림하여 주어진 숫자보다 작거나 같은 가장 큰 정수로 변환

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    double a = 3.7;
    double b = -3.7;

    cout << floor(a) << endl; // 3
    cout << floor(b) << endl; // -4

    return 0;
}

문자열 스트림(stringstream)

문자열을 마치 스트림처럼 다룰 수 있도록 해주는 클래스다.

문자열을 입력 스트림처럼 처리하여, cin에서 데이터를 추출하듯이 문자열에서도 값을 추출할 수 있다.

 

스트림은 데이터를 연속적으로 읽거나 쓸 수 있는 데이터 흐름을 말한다.

cin은 입력 스트림, cout은 출력 스트림

(아직 무슨말인지 이해가 안됨)

공백 기준으로 분리

string str = "123 X 45.67"이라는 문자열이 주어졌을 때 stringstream 이름(str)로 써서 공백기준으로 str 문자열을 분리 할 수 있다.

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main()
{
	string str = "123 X 45.67";
	stringstream stream(str);

	int num;
	char c;
	float f;

	stream >> num >> c >> f;

	cout << num << endl; // 123
	cout << c << endl; // X
	cout << f << endl; // 45.67
}

이런식으로 분리가 된다고 한다. (어떤 느낌인진 알겠는데 아직까진 어느상황에서 써야할지 잘 모르겠다.)

특정 문자 기준으로 분리

공백이 아닌 특정 문자 기준으로 분리하는 방법이다. 기본적인 원리는 이전과 비슷하지만 공백 대신 문자로 구분하기 위해서는 getline 함수를 사용해야 한다.

getline(입력 스트림, 토큰을 저장할 문자열 변수, 구분자 문자)

예를 들어 ","를 기준으로 문자열을 분리하려면 getline(ss, buf, ',')와 같이 사용하면 된다.

일반적으로 while 반복문과 함께 사용하여 문자열을 끝까지 순차적으로 분리한다.

// 목적: 쉼표(,)를 기준으로 문자열을 분할하여 토큰화
// 동작: getline() 함수를 사용하여 구분자를 지정

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    string text = "apple,banana,grape,orange";
    stringstream ss(text);
    string token;

    while (getline(ss, token, ',')) {
        cout << token << endl;
    }

    return 0;
}

/*
출력결과
apple
banana
grape
orange
*/

진법 변환(16진수와 10진수)

직접 나눗셈과 나머지를 이용해 변환 로직을 구현할 수 있지만 stringstream과 조작자(hex)를 활용하면 간단하게 처리할 수 있다.

10진수 -> 16진수

stringstream 객체에 << 연산자를 이용해 값을 출력하면 내부적으로 해당 값이 문자열로 저장되며 이때 hex 조작자를 함께 상ㅇ하면 자동으로 16진수 형식으로 변환이 된다.

// 코드의 목적 및 동작: 10진수를 16진수 문자열로 변환 후 저장
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    int decimalNumber = 4095;
    stringstream ss;

    // 1) 10진수 -> 16진수 문자열
    ss << hex << decimalNumber; // decimalNumber -> hex -> ss
    string hexStr = ss.str();

    cout << "원본 10진수 : " << decimalNumber << endl;
    cout << "16진수 문자열: " << hexStr << endl;
    
    return 0;
}
/*
    출력결과
    원본 10진수 : 4095
    16진수 문자열: fff
*/

16진수 -> 10진수

stringstream을 이용해 16진수 형식의 문자열을 읽고, 그 값을 정수형 변수에 저장해야 하므로 >> 연산자를 사용한다.

stringstream에 hex 조작자를 설정해두면 내부 문자열이 16진수로 해석되어 올바르게 정수로 변환될 수 있다.

// 코드의 목적 및 동작:
// 16진수 문자열(hex)을 입력받아 10진수(decimal) 형태의 정수로 변환
// stringstream을 활용하여 변환 후 결과 정수를 출력
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    string hexStr = "ff";
    stringstream ss(hexStr);
    int decimalNumber;

    // 16진수 형태로 파싱하도록 조작자를 설정
    ss >> hex >> decimalNumber; // ss -> hex -> decimalNumber

    cout << "16진수: " << hexStr << endl;
    cout << "10진수: " << decimalNumber << endl;

    
    return 0;
}
/*
    출력결과
    16진수: ff
    10진수: 255
*/