```
백준 3107번 IPv6 변환 C++ 구현해보기
```

이번 글을 통해 배워갈 내용
- 백준 3107번 풀이
- 간단한 IPv6 정의
IPv6 정의
IPv4가 1981년에 도입 되었을때
32 비트 주소길이, 최대 약 43억개의 주소 갯수는
많아 보였을 것이다.
예)192.168.0.0
하지만 시간이 지남에 따라 주소의 갯수가 부족해지게 되었고
128비트
43억 x 43억 x 43억 x 43억 개의
주소를 지원하는 Ipv6가 1995년에 도입이 되었다.
예) 2001:0db8:85a3:08d3:1319:8a2e:0370:7334
https://xn--3e0bx5euxnjje69i70af08bea817g.xn--3e0b707e/jsp/resources/ipv6Info.jsp
한국인터넷정보센터(KRNIC)
도메인 소개, 등록 및 사용, IP주소, AS번호, DNS 정보, 관련규정 제공
xn--3e0bx5euxnjje69i70af08bea817g.xn--3e0b707e
https://ko.wikipedia.org/wiki/IPv4
IPv4 - 위키백과, 우리 모두의 백과사전
IPv4는 인터넷 프로토콜의 4번째 판이며, 전 세계적으로 사용된 첫 번째 인터넷 프로토콜이다. 과거에 인터넷에서 사용되는 유일한 프로토콜이였으나 오늘날에는 IPv6이 대중화되었다. IETF RFC 791(1
ko.wikipedia.org
https://www.acmicpc.net/problem/3107
3107번: IPv6
첫째 줄에 올바른 IPv6 주소가 주어진다. 이 주소는 최대 39글자이다. 또한, 주소는 숫자 0-9, 알파벳 소문자 a-f, 콜론 :으로만 이루어져 있다.
www.acmicpc.net
백준 3107번 IPv6는 난이도 골드 문제로서
축약형 IPv6가 주어질때
해당되는 IPv6를 읽기 편한 형태로 바꿔주는 문제이다.
30분 정도 위에 링크를 방문하셔서 풀어보시고
안풀리시는 경우에만 아래 해답을 봐주시면 감사하겠습니다.
이 문제는 다 풀고 나서
테스트케이스를 잘못 이해하는 바람에 조금 시간이 걸렸다.
만약 답을 맞춘것 같다는 기분은 드는데 계속 틀린다면
한번 아래 테스트 케이스를
넣어 보고 다시 진행 하시길 바란다.
/*
::
0000:0000:0000:0000:0000:0000:0000:0000
::1
0000:0000:0000:0000:0000:0000:0000:0001
2001:0db8:85a3:0000:0000:8a2e:0370:7334
2001:0db8:85a3:0000:0000:8a2e:0370:7334
1:2:3:4:5:6:7::
0001:0002:0003:0004:0005:0006:0007:0000
::1:2:3:4:5:6:7
0000:0001:0002:0003:0004:0005:0006:0007
*/
10분정도 다시 풀어보고 정 안풀리면 아래 풀이를 보시면 됩니다.
입력 받고 나서
스트링으로 된 문자열을 가지고
일단 ":" 갯수를 7개로 맞춰주고
// :: 으로 이뤄진 그룹을 0000 으로 변환해준다.
// : 가 7 개 있어야 한다.
// ipv6 simple form string
std::string ipv6SFStr = ipv6StrSimplifiedForm;
// O(n)
// 콜론의 갯수를 센다.
int32_t colonCnt = count(ipv6SFStr.begin(), ipv6SFStr.end(), ':');
// 콜론의 갯수를 7개로 맞춘다.
if (colonCnt < 7)
{
std::string tempStr = "";
for (int32_t i = 0; i < (7 - colonCnt); i++)
{
tempStr += ':';
}
ipv6SFStr.replace(ipv6SFStr.find("::"), 0,tempStr);
}
//1:2:3:4:5:6:7::
if (colonCnt == 8)
{
ipv6SFStr = std::regex_replace(ipv6SFStr, std::regex("::"), ":");
}
":"씩 끊어서
4글자가 안되면 앞에 0을 넣어서
반환 스트링에 추가 해주는데 큐를 사용하였습니다.
마지막는 : 가 없어서 반복해서 코드를 쓰게 되었는데
나중에 시간이 된다면 해당되는 부분은 함수로 빼면 좋을것 같습니다.
std::string retStr = "";
std::queue<char> tempQueue;
int32_t charCnt = 4;
for (char &ch : ipv6SFStr)
{
if (ch == ':')
{
std::string tempStr = "";
if (charCnt > 0)
{
tempStr.insert(0, charCnt, '0');
}
while (tempQueue.empty() == false)
{
tempStr += tempQueue.front();
tempQueue.pop();
}
tempStr += ":";
charCnt = 4;
retStr += tempStr;
}
else
{
tempQueue.push(ch);
charCnt--;
}
}
std::string tempStr = "";
if (charCnt > 0)
{
tempStr.insert(0, charCnt, '0');
}
while (tempQueue.empty() == false)
{
tempStr += tempQueue.front();
tempQueue.pop();
}
retStr += tempStr;
ipv6Str32DigitForm = retStr;
전체 코드는 다음과 같습니다
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <array>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <regex>
class CIpv6
{
private:
std::string ipv6StrSimplifiedForm;
std::string ipv6Str32DigitForm;
public:
CIpv6()
{
ipv6StrSimplifiedForm = "";
ipv6Str32DigitForm = "";
}
~CIpv6()
{
}
void setIpv6StrSimplifiedForm(const std::string _ipv6StrSimplifiedForm)
{
this->ipv6StrSimplifiedForm = _ipv6StrSimplifiedForm;
}
void convertIpv6formTo32DigitForm()
{
// :: 으로 이뤄진 그룹을 0000 으로 변환해준다.
// : 가 7 개 있어야 한다.
// ipv6 simple form string
std::string ipv6SFStr = ipv6StrSimplifiedForm;
// O(n)
// 콜론의 갯수를 센다.
int32_t colonCnt = count(ipv6SFStr.begin(), ipv6SFStr.end(), ':');
// 콜론의 갯수를 7개로 맞춘다.
if (colonCnt < 7)
{
std::string tempStr = "";
for (int32_t i = 0; i < (7 - colonCnt); i++)
{
tempStr += ':';
}
ipv6SFStr.replace(ipv6SFStr.find("::"), 0,tempStr);
}
//1:2:3:4:5:6:7::
if (colonCnt == 8)
{
ipv6SFStr = std::regex_replace(ipv6SFStr, std::regex("::"), ":");
}
std::string retStr = "";
std::queue<char> tempQueue;
int32_t charCnt = 4;
for (char &ch : ipv6SFStr)
{
if (ch == ':')
{
std::string tempStr = "";
if (charCnt > 0)
{
tempStr.insert(0, charCnt, '0');
}
while (tempQueue.empty() == false)
{
tempStr += tempQueue.front();
tempQueue.pop();
}
tempStr += ":";
charCnt = 4;
retStr += tempStr;
}
else
{
tempQueue.push(ch);
charCnt--;
}
}
std::string tempStr = "";
if (charCnt > 0)
{
tempStr.insert(0, charCnt, '0');
}
while (tempQueue.empty() == false)
{
tempStr += tempQueue.front();
tempQueue.pop();
}
retStr += tempStr;
ipv6Str32DigitForm = retStr;
}
std::string getIpv6Str32DigitForm()
{
return ipv6Str32DigitForm;
}
};
int main()
{
std::cin.tie(NULL);
std::ios::sync_with_stdio(false);
std::string inputStr;
CIpv6* cIpv6 = new CIpv6();
std::getline(std::cin, inputStr);
cIpv6->setIpv6StrSimplifiedForm(inputStr);
cIpv6->convertIpv6formTo32DigitForm();
std::cout << cIpv6->getIpv6Str32DigitForm();
delete cIpv6;
}
읽어주셔서 감사합니다
무엇인가 얻어가셨기를 바라며
오늘도 즐거운 코딩하시길 바랍니다 ~ :)
참조 및 인용
C++ Primer
Introduction to Algorithms
https://codemasterkimc.tistory.com/35
C++ 이론을 배울수 있는 곳 정리
개요 C++을 배우는 책, 강의, 블로그, 링크 등을 공유합니다. (링크 및 간략한 설명을 하였으나 만약 원작자가 링크를 거는것을 원치 않을 경우 연락주시기 바랍니다.) 서적 https://www.amazon.com/Prime
codemasterkimc.tistory.com
https://codemasterkimc.tistory.com/50
300년차 개발자의 좋은 코드 5계명 (Clean Code)
이번 글을 통해 배워갈 내용 좋은 코드(Clean Code)를 작성하기 위해 개발자로서 생각해볼 5가지 요소를 알아보겠습니다. 개요 좋은 코드란 무엇일까요? 저는 자원이 한정적인 컴퓨터 세상에서 좋
codemasterkimc.tistory.com
'C++ > C++ 알고리즘' 카테고리의 다른 글
| 백준 23037번 5자리 각 숫자 5제곱 해서 더하기 (0) | 2021.09.12 |
|---|---|
| 백준 20499번 K/D/A 점수변환 C++ 구현해보기 (0) | 2021.09.12 |
| 백준 2718번 4 X N 타일 채우기 C++ 구현해보기 (0) | 2021.09.11 |
| 백준 11727번 2xn 타일링2 C++ 구현해보기 (0) | 2021.09.11 |
| 백준 11726번 2xn 타일링 C++ 구현해보기 (0) | 2021.09.11 |