본문 바로가기
개발/C, C++

셔플 Shuffle - 카드 섞기 알고리즘

by 피로물든딸기 2022. 7. 8.
반응형

C, C++ 전체 링크

삼성 C형 전체 링크

 

1~10까지 카드가 있다고 가정하자.

이때, 카드를 N번(20) 적당히 섞어보자.

 

stdlib.h를 선언하면 rand()함수를 이용할 수 있다.

카드가 총 10장이므로 카드의 size = 10으로 rand() % size를 하면 10장 중 1개의 카드를 랜덤으로 고를 수 있다.

카드를 2장 랜덤으로 골라 교환하면 카드가 섞인다.

#include <stdio.h>
#include <stdlib.h> /* rand() 사용을 위한 선언 */

int main(void)
{
	int N = 20;
	int card[] = { 1,2,3,4,5,6,7,8,9,10 };
	int size = sizeof(card) / sizeof(int);

	for (int i = 0; i < N; i++) /* N번 교환 */
	{
		int a = rand() % size;
		int b = rand() % size;

		int tmp = card[a];
		card[a] = card[b];
		card[b] = tmp;
	}

	for (int i = 0; i < size; i++) printf("%d ", card[i]);
	putchar('\n');

	return 0;
}

 

하지만 이 코드를 아무리 발생해도 같은 결과가 나온다.

이유는 rand()함수의 난수표가 고정이기 때문이다.

난수표를 바꾸고 싶으면 srand를 이용하면 된다. (time.h 선언이 필요하다)

#include <stdio.h>
#include <stdlib.h> /* rand() 사용을 위한 선언 */
#include <time.h> /* srand() 사용을 위한 선언 */

int main(void)
{
	int N = 20;
	int card[] = { 1,2,3,4,5,6,7,8,9,10 };
	int size = sizeof(card) / sizeof(int);

	srand(5);

	for (int i = 0; i < N; i++) /* N번 교환 */
	{
		int a = rand() % size;
		int b = rand() % size;

		int tmp = card[a];
		card[a] = card[b];
		card[b] = tmp;
	}

	for (int i = 0; i < size; i++) printf("%d ", card[i]);
	putchar('\n');

	return 0;
}

 

아까와 다른 결과가 나왔지면, 여전히 코드를 실행하면 같은 결과가 나온다.

srand(5)로 인해 난수표가 변경되었으나, 여전히 변경된 난수표로 고정되었기 때문이다.

 

srand(time(NULL));을 해주면 매번 실행 때마다 난수표가 변경된다.

#include <stdio.h>
#include <stdlib.h> /* rand() 사용을 위한 선언 */
#include <time.h> /* srand() 사용을 위한 선언 */

int main(void)
{
	int N = 20;
	int card[] = { 1,2,3,4,5,6,7,8,9,10 };
	int size = sizeof(card) / sizeof(int);

	srand(time(NULL)); /* 실행할 때 마다 난수표 변경 */

	for (int i = 0; i < N; i++) /* N번 교환 */
	{
		int a = rand() % size;
		int b = rand() % size;

		int tmp = card[a];
		card[a] = card[b];
		card[b] = tmp;
	}

	for (int i = 0; i < size; i++) printf("%d ", card[i]);
	putchar('\n');

	return 0;
}

매번 실행 때마다 카드가 랜덤으로 섞여있는 것을 알 수 있다.

반응형

댓글