최고의 답변자
[VB6][TIP] 1 부터 10 까지의 수를 '중복 없이' 랜덤하게 6개 뽑기 문제에 대한 TIP

질문
답변
-
우선, 다들 아시다시피 랜덤하게 수를 뽑는 방법은 아래와 같이 구현할 수 있답니다. :)
Dim randomNum As Integer
Randomize
randomNum = Int(Rnd * 10) + 1그런데, 저 소스 코드가 어떤 원리로 동작하는지 모르시는 분들을 위해 Rnd() 함수를 설명하겠습니다. :)
Rnd() 함수는 아래 조건을 만족하는 'X' 값을 무작위로 반환하는 함수입니다.
0 ≤ X < 1사실 Rnd도 내부적으론 '난수 계열'이라는 표 비슷한 것을 사용합니다.
이것을 랜덤하게 초기화 시켜주는 녀석이 Randomize() 함수입니다.
이 함수는 아래와 같은 용법으로 사용할 수 있습니다. (과거 큐 베이직때는 다른 용법으로 사용했습니다.)
Randomize
따라서, Rnd () 함수로 1부터 10까지 뽑아오려면 아래와 같이 해야합니다.Rnd () =
0.00001 … ~ 0.99999 …
Rnd () * 10 =
0.00001 … ~ 9.99999 …Int(Rnd () * 10) =
0 ~ 9Int(Rnd () * 10) + 1 =
1 ~ 10위와 같은 방법으로 구할 수 있습니다.
(Int() 함수는 버그가 존재하므로, CInt/CLng나 Fix를 쓰는 것을 추천합니다.)그런데, 위와 같은 방법으로 구할 때, 겹치지 않고 6개를 뽑을 수 있을까요?
위와 같은 방법으로 뽑으면 같은 수가 2번 이상 나오지 않는다는 보장도 없을테고….간단한 방법은, 배열 (Array)을 이용하는 방법이 있습니다.
배열에 1부터 10까지 저장한 뒤, 하나씩 빼는 알고리즘을 이용하면 됩니다.아래는 그런 방법으로 구현한, 1~10 중 6개를 랜덤하게 중복없이 뽑는 방법을 보여주는 예제입니다.
Sub Main()
Dim arrCol As Integer, arrIndex As Integer, strChosen As String, lngCount As Long
Dim arrNumbers() As Integer ' 1 ~ 10을 저장하는 동적 배열
ReDim arrNumbers(9) ' 10개의 배열 첨자 동적 생성
Randomize ' 난수 초기화
For arrCol = 0 To 9 ' 배열의 값을 설정합니다.
arrNumbers(arrCol) = arrCol + 1
Next
Do While lngCount < 6 ' 총 6회 반복
arrIndex = Int(Rnd * (UBound(arrNumbers) + 1))
' 무작위로 랜덤한 하나의 첨자를 구함
If strChosen = "" Then
strChosen = CStr(arrNumbers(arrIndex))
Else
strChosen = strChosen & ", " & CStr(arrNumbers(arrIndex))
End If
' 결과에 더함
arrNumbers(arrIndex) = arrNumbers(UBound(arrNumbers))
' 현재 구한 배열의 첨자에 맨 끝 첨자의 값을 대입함.
ReDim Preserve arrNumbers(UBound(arrNumbers) - 1)
' 맨 끝 첨자를 제거함.
lngCount = lngCount + 1
' 카운트 변수 증가
Loop
Erase arrNumbers ' 배열을 메모리상에서 제거
MsgBox strChosen ' 결과 출력
End Sub- 답변으로 표시됨 devlife 2012년 6월 29일 금요일 오전 10:57
모든 응답
-
우선, 다들 아시다시피 랜덤하게 수를 뽑는 방법은 아래와 같이 구현할 수 있답니다. :)
Dim randomNum As Integer
Randomize
randomNum = Int(Rnd * 10) + 1그런데, 저 소스 코드가 어떤 원리로 동작하는지 모르시는 분들을 위해 Rnd() 함수를 설명하겠습니다. :)
Rnd() 함수는 아래 조건을 만족하는 'X' 값을 무작위로 반환하는 함수입니다.
0 ≤ X < 1사실 Rnd도 내부적으론 '난수 계열'이라는 표 비슷한 것을 사용합니다.
이것을 랜덤하게 초기화 시켜주는 녀석이 Randomize() 함수입니다.
이 함수는 아래와 같은 용법으로 사용할 수 있습니다. (과거 큐 베이직때는 다른 용법으로 사용했습니다.)
Randomize
따라서, Rnd () 함수로 1부터 10까지 뽑아오려면 아래와 같이 해야합니다.Rnd () =
0.00001 … ~ 0.99999 …
Rnd () * 10 =
0.00001 … ~ 9.99999 …Int(Rnd () * 10) =
0 ~ 9Int(Rnd () * 10) + 1 =
1 ~ 10위와 같은 방법으로 구할 수 있습니다.
(Int() 함수는 버그가 존재하므로, CInt/CLng나 Fix를 쓰는 것을 추천합니다.)그런데, 위와 같은 방법으로 구할 때, 겹치지 않고 6개를 뽑을 수 있을까요?
위와 같은 방법으로 뽑으면 같은 수가 2번 이상 나오지 않는다는 보장도 없을테고….간단한 방법은, 배열 (Array)을 이용하는 방법이 있습니다.
배열에 1부터 10까지 저장한 뒤, 하나씩 빼는 알고리즘을 이용하면 됩니다.아래는 그런 방법으로 구현한, 1~10 중 6개를 랜덤하게 중복없이 뽑는 방법을 보여주는 예제입니다.
Sub Main()
Dim arrCol As Integer, arrIndex As Integer, strChosen As String, lngCount As Long
Dim arrNumbers() As Integer ' 1 ~ 10을 저장하는 동적 배열
ReDim arrNumbers(9) ' 10개의 배열 첨자 동적 생성
Randomize ' 난수 초기화
For arrCol = 0 To 9 ' 배열의 값을 설정합니다.
arrNumbers(arrCol) = arrCol + 1
Next
Do While lngCount < 6 ' 총 6회 반복
arrIndex = Int(Rnd * (UBound(arrNumbers) + 1))
' 무작위로 랜덤한 하나의 첨자를 구함
If strChosen = "" Then
strChosen = CStr(arrNumbers(arrIndex))
Else
strChosen = strChosen & ", " & CStr(arrNumbers(arrIndex))
End If
' 결과에 더함
arrNumbers(arrIndex) = arrNumbers(UBound(arrNumbers))
' 현재 구한 배열의 첨자에 맨 끝 첨자의 값을 대입함.
ReDim Preserve arrNumbers(UBound(arrNumbers) - 1)
' 맨 끝 첨자를 제거함.
lngCount = lngCount + 1
' 카운트 변수 증가
Loop
Erase arrNumbers ' 배열을 메모리상에서 제거
MsgBox strChosen ' 결과 출력
End Sub- 답변으로 표시됨 devlife 2012년 6월 29일 금요일 오전 10:57