[BOJ] 3107번_IPv6_문자열 (C++)

ChangBeom·2024년 10월 30일

Algorithm

목록 보기
88/97

[문제]

https://www.acmicpc.net/problem/3107

IPv6은 길이가 128비트인 차세대 인터넷 프로토콜이다.
IPv6의 주소는 32자리의 16진수를 4자리씩 끊어 나타낸다. 이때, 각 그룹은 콜론(:)으로 구분해서 나타낸다.

예를 들면, 다음과 같다.

2001 : 0db8 : 85a3 : 0000 : 0000 : 8a2e : 0370 : 7334

32자리의 16진수는 사람이 읽고 쓰기에 불편하고, 대부분의 자리가 0이기 때문에 아래와 같이 축약할 수 있다.

1. 각 그룹의 앞자리의 0의 전체 또는 일부를 생략할 수 있다. 위의 IPv6을 축약하면, 다음과 같다.

2001 : db8 : 85a3 : 0 : 00 : 8a2e : 370 : 7334


2. 만약 0으로만 이루어져 있는 그룹이 있을 경우 그 중 한 개 이상 연속된 그룹을 하나 골라 콜론 2개(::)로 바꿀 수 있다.

2001 : db8 : 85a3 :: 8a2e : 370 : 7334

2번째 규칙은 모호함을 방지하기 위해서 오직 한 번만 사용할 수 있다.

올바른 축약형 IPv6주소가 주어졌을 때, 이를 원래 IPv6 (32자리의 16진수)로 복원하는 프로그램을 작성하는 문제이다.

[사용 알고리즘]

문자열

[풀이 핵심]

  • 문자열을 다루는 문제지만, 사실 구현문제에 가깝다고 볼 수 있다.
  • 먼저 입력받은 IPv6 주소를 문자열 split을 구현해서 vector에 저장한다. (C++은 문자열 split을 STL이 없어 따로 구현해야한다.)
  • 문자열 split을 할 때 "::"가 나온경우(":"가 나왔는데 temp가 비어 있으면 "::"라고 판단) IPv6에서 사용하지 않는 아무 알파벳 대문자(필자는 "A"를 사용하였다.)를 push해준다.
  • 이제 저장한 데이터를 탐색하며 "A"가 있으면 총 8자리 수에서 부족한 자리수 만큼 "0000"을 push해준다.
  • 마지막으로 다시 한번 저장한 데이터를 탐색하며 "0"이 생략된 경우 "0"을 추가해준다.

*항상 구현 문제를 풀다보면 코드가 길고 더러워지는 것 같다. 다음부턴 최대한 깔끔하게 짜는 연습을 해야할 것같다.

[코드]


//boj3107번_IPv6_문자열

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main() {
	string ip;
	cin >> ip;

	vector<string> v;

	string temp = "";

	bool check = false;

	for (int i = 0; i < ip.size(); i++) {
		if (ip[i] == ':') {
			if (temp == "" && check == false) {
				v.push_back("A");
				check = true;
			}
			else {
				v.push_back(temp);
				temp = "";
			}
		}
		else {
			temp += ip[i];
		}
	}

	v.push_back(temp);

	vector<string> ip_result;

	for (int i = 0; i < v.size(); i++) {
		if (v[i] == "A") {
			for (int j = 0; j < 9 - v.size(); j++) {
				ip_result.push_back("0000");
			}
		}
		else {
			ip_result.push_back(v[i]);
		}
	}

	string result = "";

	for (int i = 0; i < ip_result.size(); i++) {
		string str = "";
		int count = 0;

		for (int j = 0; j < 4 - ip_result[i].size(); j++) {
			str += "0";
		}

		if (i != ip_result.size() - 1) {
			str += ip_result[i] + ":";
		}
		else {
			str += ip_result[i];
		}

		result += str;
	}

	cout << result;

	return 0;
}

0개의 댓글