PGR21.com
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
Date 2008/06/21 00:37:59
Name EZrock
Subject C 난수생성 질문입니다.
#include <stdio.h>
#include <stdlib.h>
#include "windows.h" // GetTickCount()

#define MAX_BOX_SIZE 1000
#define MAX_SIZE 10

int main(void)
{
        int a,i,j;
        int gene_num;

        int temp_gene_num[MAX_BOX_SIZE][MAX_SIZE] = {0,};

        srand((unsigned int) GetTickCount());
        
        // 번호 생성+배열에 넣는다.
        for(a=0; a<MAX_BOX_SIZE; a++){

                for(i=0; i<MAX_SIZE; i++){

                        gene_num = rand()%100+1;

                        for(j=0; j<=i; j++){
                                if(temp_gene_num[i][j] == 0) temp_gene_num[i][j] = gene_num;
                                else if(gene_num == temp_gene_num[i][j]) {
                                        gene_num = rand()%100+1;
                                        continue;
                                }
                        }

                        printf("%d ",temp_gene_num[i][j]);
                }

                printf("\n");

        }

        return 0;
}

1~100까지의 난수생성을 해서 서로다른 수로 10칸 채워넣는 작업을 1000번 반복하는 프로그램입니다.

처음에는 단순히 1차원배열만 썼는데 결과값 10개의 수가 계속 똑같이 1000번 반복되는 것입니다.

그래서 이번엔 아예 2차원배열로 했더니 이번엔 출력값이 다 0이 뜨고 만 것입니다.

처음에는 알고리즘 자체가 잘못되서 헤맸다가 이번엔 분명 이론상으론 문제가 없으리라 생각했는데 꼬여서 또 몇시간째 붙잡고 있습니다.

이걸 어떻게 해결해야 할까요?

게다가...원래는 저 앞에 인덱스를 가지는 구조체배열로 만들려고 했습니다.

typedef struct {
     int index;
     int value[MAX_SIZE];
} Element;

Element temp_gene_num[MAX_BOX_SIZE];

이런식으로 할려고 했는데 초기화 부분을 엄두조차 낼수가 없어서 일단 저거부터 해결하고 보자로 넘어갔습니다.

우선 한번만 실행시키면 난수는 겹치지 않고 완성이 됩니다.

하지만 그 이후부터 1차원 배열만으로 만들려니 중복이 되고 2차원배열로 가니까 모든 원소가 0이 되는 바람에 이젠 손을 쓸 도리조차 없습니다.

어떻게 난수처리를 해결해야 할지

그리고 구조체 배열로 쓸려고 하면 어떤식으로 접근을 해야 할지 좀 알려주셨으면 합니다.

통합규정 1.3 이용안내 인용

"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
부엉군
08/06/21 01:47
수정 아이콘
구조체 배열 초기화는 그냥 for 문 돌면서 해주시면 되구요..
랜드 함수 문제는 디버거로 보면서 문제점 아시는게 장기적으로 봤을 때 훨씬 좋을 것 같네요.. (디버거 사용법 한 30분이면 충분히 익히니.)
08/06/21 02:06
수정 아이콘
한줄씩 죽 훑어 봤는데요
버그란 녀석은 역시 의외의 장소에서 나오나 봅니다.
temp_gene_num[i][j] 를 temp_gene_num[a][j] 로 바꾸어야 겠네요
한번 테스트 해보니 대충 맞게 돌아가는군요
이런 경우가 많으니 index가 여러개가 되면 꼭 하나씩 확인하세요( 저같은 경우 3일을 헤맨 경우가 ㅠ.ㅠ 디버거는 꼭 필요합니다!!)
08/06/21 02:11
수정 아이콘
아참 추가로 중복체크하는 부분에 문제가 조금 보입니다.
하나의 중복이 나오면 새로 난수를 생성하고(index = n), 그다음 중복체크는 continue에 의해 index = n+1부터 시작되는 걸로 보입니다. 간단한 테스트 방법으론 #define MAX_SIZE 10 를 하면 눈에 바로 보입니다. 조금더 생각해 보시구요, 힘내세요~
전 이만 텀플하러 슝~
08/06/21 03:09
수정 아이콘
음...continue에 그런 문제가 있었군요.

근데 일단 [a][j]로 고치고 continue부분을 고쳐서 새로 생성된 부분을 기존의 중복되는 temp_gene_num[j]과 매치시켜서 중복이 안나올때까지 while루프로 계속 중복 안나오게 만드는 부분을 추가하니까 중복이 더 심해지더군요-_-);;

for(j=0; j<=i; j++)

if(temp_gene_num[a][j] == 0) temp_gene_num[a][j] = gene_num;
else if(temp_gene_num[a][j] == gene_num) {
while(gene_num != temp_gene_num[a][j]){
gene_num = rand()%100+1;
if(gene_num != temp_gene_num[a][j]) temp_gene_num[a][j] = gene_num;

}
}

...가면 갈수록 첩첩산중입니다. 가만 놔두니까 오히려 중복률이 훨씬 적은 편이지만...그걸로 안주할 생각은 없으니 말입니다.
08/06/21 05:07
수정 아이콘
음.... 시작하는 프로그래머에게 좋은 화두가 되는 문제내요.

예전부터 있던 문제인데...

0~99 까지 있는 배열을 어떻게 하면 잘 섞을까 하는 문제의 변형 같습니다.

수 많은 난상 토론이 이루어진적이 있지만... 누구도 이것이 옵티말 이다 한 답이 없던 것으로 알고 있습니다. 저 역시 나름의 답이 있지만...
그것이 옵티말 인지는 모르겠습니다. 아무튼 머리잘써서 생각해 보세요. 곰씹으면 꼽씹을수록 단맛이 나는 문젱 입니다.
彌親男
08/06/21 10:26
수정 아이콘
흠흠.... 그럴 경우에는 goto문을 써서 하면 괜찮습니다.

아니면 이런 방식으로 접근해도 괜찮습니다. 잠깐 알고리즘만 써드릴테니까 코드로 짜 보세요.

gene_num = rand()%100 + 1;
while(gene_num == temp_gene_num)
gene_num = (gene_num + 1) % 100;


만약 같다면 다시 랜덤을 생성하는 것보다는 그 값에 1을 계속 더하면서 가장 가까운 빈자리에 집어넣으면 확실합니다. 이렇게 하는 것이 time complexity도 더 짧기 때문에 좋아요.
부엉군
08/06/21 13:41
수정 아이콘
↑위에 처럼 하면 time complexity 는 짧은데 이상적인 난수라 보기는 어려울 수 있을 것 같네요..
(혹시 언뜻 생각하기에는 아닌데 계산해보면 같게 나오는 경우인가요?)
ShadowChaser
08/06/21 14:39
수정 아이콘
srand ... random seed 값을 가져와야죵...
08/06/21 15:40
수정 아이콘
random seed값을 2번 가져올순 없는 모양입니다. 그렇게 하니까 똑같은 연산을 반복해서 여전히 같은값을 출력하는건 같았습니다.

곱씹어 보라했는데 저 알고리즘을 가지고 한 10번 고쳤다면 이 이상 곱씹어 볼 방법이 있을까 싶습니다.

재생성이 필수인데 재생성의 의미가 없어지는 2번째 gene_num = rand()%100+1; 입니다.
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
38394 C 난수생성 질문입니다. [9] EZrock2103 08/06/21 2103
38393 콘돔 질문입니다.. [14] 여보야5553 08/06/21 5553
38392 컴퓨터 새로 장만하려하는데 도움을 구합니다- [4] 새벽오빠1581 08/06/20 1581
38391 여성용 피임약에 대하여 질문입니다. [8] Sinder2518 08/06/20 2518
38390 성시경 - 안녕 나의 사랑 가사.. [9] worcs10775 08/06/20 10775
38389 ipod touch관련해서 궁금한점이 있습니다. [2] 코파지마1828 08/06/20 1828
38388 캐리비안 베이에 놀러갈 예정입니다 그런데.. [3] axbycz1902 08/06/20 1902
38387 대인관계 문제입니다... [11] 강희최고1971 08/06/20 1971
38385 비스타 깔아보려고 하는데.. 어떤가요? [8] 꿀빵1564 08/06/20 1564
38384 노트북관련 질문 좀 드릴께요~ [3] 4드론1602 08/06/20 1602
38381 치아에서 피가납니다. [10] 컨트롤황제1869 08/06/20 1869
38380 요새 야구계 이슈는 뭐죠? [10] lxl기파랑lxl1894 08/06/20 1894
38379 이런식으로 염색하려면요~ [1] Xavi1880 08/06/20 1880
38378 엑박 문제좀 해결해주세요. Fly:D3009 08/06/20 3009
38377 [WOW] 질문입니다. 성기사 특성 [5] 낭만토스2283 08/06/20 2283
38376 하모니카에 대해 질문이 있습니다. Anarchie1708 08/06/20 1708
38375 노래방 알바에대해서 질문좀 할께요^^ [9] wAvElarva1883 08/06/20 1883
38374 컴고수님들!! 컴퓨터 질문입니다. [2] 학몽1510 08/06/20 1510
38373 피지알엔 어쩌다 들어오게 되셨어요? [26] 먹도1766 08/06/20 1766
38372 쿵푸팬더 관련 질문입니다 :) [2] 눈팅만7년째1884 08/06/20 1884
38371 저도 피부에 관한 질문 드립니다. [1] 오뱅1705 08/06/20 1705
38368 맥북 침수후 자주 다운이 됩니다 [3] prestonia2155 08/06/20 2155
38366 일어 숫자말에 대해서 좀 아시는분 계셔요? [6] SniperWolf2312 08/06/20 2312
목록 이전 다음
댓글

+ : 최근 6시간내에 달린 댓글
+ : 최근 12시간내에 달린 댓글
맨 위로