본문 바로가기

C++

C++ 배우기 6(이중for문, 스왑, 셔플)

이중 for 문

for(int i = 0; i < 5; i++)
{
	for(int j = 0; j < 5; j++)
    {
    
    }
}

앞서 이중 for문을 사용하여 로또번호 자동 생성기를 좀 더 효율적으로 코딩할 수 있었다.

이중 for문이란, 말 그대로 for문 안에 for문을 넣어 이중으로 사용한다는 뜻이다.

그리고 이중 for문하면 떠오르는 바로 그것, '별 찍기'이다.

마침 오늘 숙제 중 하나가 별 찍기여서 조금 어려웠었다...ㅎㅎ;;

이중 for문의 정수 "별찍기"


셔플 알고리즘

앞서 우리는 랜덤 한 값을 넣기 위해서 랜덤함수를 사용했었다. 하지만 랜덤함수에는 중복된 값이 가끔 나올때가 있었는데,

셔플 알고리즘을 사용하면 중복되는 값 없이, 랜덤한 값을 나타낼 수 있다.

우선 셔플은 우리가 알던 카드를 섞는 그런 행위를 일컫는 말이다. 아마 셔플 알고리즘이 작동하는 느낌이 카드를 섞는,

그런 느낌과 비슷하여 부르는 것 같다.


스왑 알고리즘

먼저 스왑 알고리즘부터 알고 넘어가야 한다.

//카드뭉치 deck
int deck[50];

//스왑swap 알고리즘
int temp;
temp = deck[0];
deck[0] = deck[1];
deck[1] = temp;

int 자료형의 배열 deck [50]을 선언했다. 그런데 deck [0]과 deck [1]의 값을 서로 바꿔주고 싶다면 어떻게 해야 할까?

이렇게 하면 될까?

위의 방법처럼 했다간 deck [0]의 값이 사라져 버리고 deck [1]의 값만 남게 될 것이다.

그러면 deck [0]에 deck [1]의 값을 넣어주기 전에 deck [0]의 값을 임시로 저장할 곳을 만들어 저장해두면 되지 않을까?

 

스왑 알고리즘의 원리

위의 방법처럼 임시 저장할 변수 temp를 선언 후에 deck [0]의 값을 저장해두면 사라지는 값 없이 무사히 스왑이 된다.

이와 같은 작동방식을 알아두면 된다.


다시 셔플 알고리즘으로 넘어와서...

//카드뭉치 deck
int deck[50]; //선언

//정의
for (int i = 0; i < 50; i++)
{
    deck[i] = i + 1;
}

//호출
for (int i = 0; i < 50; i++)
{
    cout << deck[i] << endl;
}

//===================================================

//셔플
for (int i = 0; i < 1000; i++)
{
    int sour = rand() % 50; // 0 ~ 49
    int dest = rand() % 50;
    int temp;

    temp = deck[sour];
    deck[sour] = deck[dest];
    deck[dest] = temp;
}

다시 deck [50] 배열을 선언, 정의, 호출까지 해서 잘 실행되는지 확인해보았다.

그리고 셔플 알고리즘을 사용해서 deck[50]배열 안의 숫자를 무작위로 위치를 바꾸어주는 것이다.

바로 배열의 index 값들을 랜덤 함수를 이용해서 바꿔주면, 중복되는 값 없이 뒤죽박죽으로 값들이 섞이게 된다.

 

이게 셔플 알고리즘의 작동방식이다.