(1) Next_permutation 함수란?

범위의 요소를 [first,last]다음 사전 식으로더 큰 순열로 다시 정렬합니다. 

 ex) 1,2,3 -> 1,3,2 -> 2,1,3 -> 2,3,1 -> 3,1,2 -> 3,2,1

단, 1,3,2 에서 시작 시 1,2,3의 경우는 돌아가지 않는다.


(2) Next_permutation 함수 구조

  • 필요 헤더  
#include <algorithm>

 

  • 템플릿
//default
template <class BidirectionalIterator>
  bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last);

//custom(비교문을 넣을 수 있음)                         
template <class BidirectionalIterator, class Compare>
  bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last, Compare comp);
                         
 <------------------------예제------------------------>
#include <iostream>     // std::cout
#include <algorithm>    // std::next_permutation, std::sort

int main () {
  int myints[] = {1,2,3};

  std::sort (myints,myints+3);

  std::cout << "The 3! possible permutations with 3 elements:\n";
  do {
    std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
  } while ( std::next_permutation(myints,myints+3) );

  std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';

  return 0;
}

(3) Next_permutation 사용법

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

using namespace std;

int main()
{
	vector<int> v;

	v.push_back(2);
	v.push_back(1);
	v.push_back(3);

//모든 경우의 수를 확인하기 위해 최초 벡터를 오름차순으로 정렬
	sort(v.begin(), v.end());
	
	do {
		for (int i = 0; i < v.size(); i++)
		{
			cout << v.at(i);
		}
		cout << endl;
	} while (next_permutation(v.begin(), v.end()));

	return 0;
}

실행결과

 

아래 링크를 통해 Next_permutation 함수를 사용한 완전탐색예제를 확인하실수 있습니다.

 

2020/11/27 - [Programmers/C++] - [프로그래머스] 코딩테스트 연습 > 완전탐색 > 소수 찾기(C++)


'Study > C++' 카테고리의 다른 글

[TCP] TCP - Server  (2) 2020.11.06
[STL] Vector Container 기본 사용법  (0) 2020.10.21

(1) TCP 란?

Transmission Control Protocol의 축약어로 컴퓨터가 다른 컴퓨터와 데이터 통신을 하기 위한 규약(프로토콜)의 일종이다. 


(2) TCP 특징

  • 연결형 서비스로 가상 회선 방식을 제공

  • 3-way handshaking과정을 통해 연결을 설정하고 4-way handshaking을 통해 해제

  • 흐름 제어 및 혼잡 제어

  • 높은 신뢰성을 보장

  • UDP보다 속도가 느림

TCP 연결 과정


(3) Code - Server

#include <winsock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

using namespace std;

void ErrorHandling(string message);

#define PORT 1000
#define BUFFER_SIZE 1024

int main()
{
	WSADATA     wsaData;
	SOCKET      hServSock, hClntSock;
	SOCKADDR_IN servAddr, clntAddr;

	memset(&wsaData, 0x00, sizeof(WSADATA));
	memset(&hServSock, 0x00, sizeof(SOCKET));
	memset(&hClntSock, 0x00, sizeof(SOCKET));
	memset(&servAddr, 0x00, sizeof(SOCKADDR_IN));
	memset(&clntAddr, 0x00, sizeof(SOCKADDR_IN));


	bool	bAccept = false;
	bool	bBind = false;
	int     szClntAddr = 0;
	bool	bBind = false;

	while (1)
	{
		if (!bAccept)
		{
			if (!bBind)
			{
				// 윈속 초기화, 소켓사용하기전 초기화 해야함
				if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
					ErrorHandling("WSAStartup() error!");

				// TCP 소켓생성
				hServSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

				int opt = 1;

				ioctlsocket(hServSock, FIONBIO, (u_long*)&opt);

				if (hServSock == INVALID_SOCKET)
					ErrorHandling("socket() error!");

				servAddr.sin_family = AF_INET;
				servAddr.sin_addr.s_addr = htonl(INADDR_ANY); 	// 현재 PC IP주소 사용
				servAddr.sin_port = htons(PORT);	// 포트번호

				// 주소 지정
				if (bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
					ErrorHandling("bind() error!");

				bBind = true;
			}
			else
			{
				// 접속 받을수 있게
				if (listen(hServSock, 5) == SOCKET_ERROR)
					ErrorHandling("listen() error!");

				// 연결 수락
				szClntAddr = sizeof(clntAddr);

				hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr);   
				if (hClntSock == INVALID_SOCKET)
					ErrorHandling("accept() error!");
				else
					bAccept = true;				
			}
		}
		else if (bBind && bAccept)
		{
			char cBuffer[BUFFER_SIZE] = {};
			int size = 0;

			size = recv(hClntSock, cBuffer, BUFFER_SIZE, 0);

			if (size > 0)
			{
				cout << cBuffer << endl;
			}			
		}
	}
	return 0;
}

void ErrorHandling(string message)
{
	cout << message << endl;
}

 

'Study > C++' 카테고리의 다른 글

[STL] Next_permutation 함수 (C++)  (0) 2020.11.27
[STL] Vector Container 기본 사용법  (0) 2020.10.21

(1) Vector란?

Vector는 C++ 표준 라이브러리(Standard Template Library)에 있는 컨테이너로 사용자가 손쉽게 사용하기 위해 정의된 class입니다. Vector의 가장 큰 장점은 동적으로 원소를 추가할 수 있으며 크기가 자동으로 늘어난다는 점입니다. 쉽게 말해 크기가 가변적으로 변하는 배열이라고 할 수 있습니다. 속도적인 측면에서는 배열에 비해 떨어지지만 메모리를 효율적으로 관리할 수 있다는 장점이 있어 굉장히 많이 사용합니다. vector는 배열과 마찬가지로 원소들이 하나의 메모리 블록에 연속하게 저장됩니다. 그렇기에 원소가 추가되거나 삽입될 때 메모리 재할당이 발생할 수 있고 상당한 부하가 발생하게 된다는 점은 단점으로 꼽히고 있습니다.


(2) Vector 구조

vector를 생성하면 메모리 heap에 생성되며 동적 할당됩니다.

front() : 첫 번째 원소
back() : 마지막 원소
begin() : 첫번째 위치
end() : 마지막의 다음 위치
size() : 원소의 개수
capacity() : 할당된 공간의 크기

 

size와 capacity가 따로 있는 이유

매번 새로운 원소가 들어올 때마다 새로운 메모리가 할당되는 것은 비효율적입니다. 그렇기에 vector는 새로운 원소가 벡터에 추가되면 메모리 공간을 추가적으로 할당되는 방식으로 이루어져 있습니다. 좀 더 정확하게는 capacity가 모자랄 경우 capacity/2 만큼의 capacity를 늘려나가게 됩니다. 만약 입력될 원소의 개수를 알 수 있다면 reserve를 사용하여 미리 capapcity 메모리를 할당해 놓으면 좀 더 호율적으로 vector를 사용할 수 있습니다.


(3) Vector 사용법

  • vector Container를 사용하기 위한 헤더
#include <vector>
  • Vector <T> 변수명 : T자료형을 가진 Vector 변수명을 선언
vector<int> _Vector
  • push_back(const T& x) : 벡터 끝에 원소를 추가
  • pop_back : 벡터의 마지막 원소를 삭제
  • insert(iterator position, const value_type& val) : position에 val를 삽입
  • erase(iterator position) : position에 위치한 값 삭제
_Vector.push_back(10);		// 벡터의 끝에 10값을 삽입
_Vector.pop_back;		// 벡터의 마지막 원소 삭제
_Vector.insert(3,10);		// 3번째에 10 삽입 //_Vector.insert(i,val)
_Vector.erase(3);		// 3번째값 삭제 //_Vector.erase(i)
  • begin() : 벡터의 시작 원소를 가리키는 반복자를 반환
  • end() : 벡터의 끝 표시 반복자를 반환
  • at() : 벡터의 n에 있는 원소를 반환
_Vector.begin();
_Vector.end();
_Vector.at(i);

 

'Study > C++' 카테고리의 다른 글

[STL] Next_permutation 함수 (C++)  (0) 2020.11.27
[TCP] TCP - Server  (2) 2020.11.06

+ Recent posts