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