묻고답하기
page_full_width" class="col-xs-12" |cond="$__Context->page_full_width">
[자문자답] rand()을 이용한 순서뒤섞기?????
2002.05.08 08:47
안녕하세요?
페이지를 로딩할때마다 다수의 등록된 음악의 순서가 뒤섞여 다른 순서대로 재생하려고합니다.
물론 페이지가 로딩될때 여러음악이나 이미지중에서 하나를 랜덤하게 추출해서 뿌려주는건 이해가되고 실제로 활용도하고 있습니다만, 이놈도 비슷할것같은데 의외로 당췌.... ^^;;
머리가 정말 스톤인가봅니다... ㅠ..ㅠ
예를들어, m1 ~ m5의 음악이 있다고 할때 접속할때마다 아래와 같이 순서가 막 뒤섞이게하려합니다.
case1 : m1,m3,m5,m4,m2
case2 : m3,m2,m5,m1,m4
...............
rand() 또는 mt_rand()을 써서 1 ~ 5까지 임의의 숫자를 추출해서 뿌릴려고시도했습니다만, 문제는 숫자가 중복되어 나오는 경우인데 1 ~ 5가 하나씩 모두 나타나게하려니...
대략적인 소스는 아래와 같습니다. (m1~m5의 음악을 임의의 순서대로 하나씩 music.asx에 저장하여 재생하는 형식입니다)
답변해주심 무척 감사하겠습니다... (--)(__)
##########################################
$song_no = 5;
$m[1] = "mms://xxx/1.wma";
$m[2] = "mms://xxx/2.wma";
$m[3] = "mms://xxx/3.wma";
$m[4] = "mms://xxx/4.wma";
$m[5] = "mms://xxx/5.wma";
for ($i=1;$i<=$song_no;$i++) {
mt_srand ((double) microtime() * 1000000);
$music[$i] = $m[mt_rand(1,$song_no)];
}
for ($k=1;$k<=$song_no;$k++) {
$list .= "$music[$k]n";
$fp=fopen(music.asx,"w");
flock($fp,2);
fwrite($fp,$list);
fclose($fp);
}
############################################
++++++++++++++++++++++++++++++++++++++++++++
고민하다 아래와 같은 허덥한 방법으로 해결했습니다. -,.-;;
진짜 알고리즘같은 방법을 아시는 분은 리플 좀 달아주세요...
$song_no = 5;
$m[1] = "mms://xxx/1.wma";
$m[2] = "mms://xxx/2.wma";
$m[3] = "mms://xxx/3.wma";
$m[4] = "mms://xxx/4.wma";
$m[5] = "mms://xxx/5.wma";
for ($i=1;$i<=$song_no;$i++) { // 난수발생루틴
mt_srand ((double) microtime() * 1000000);
$music[$i] = $m[mt_rand(1,$song_no)];
for ($r=1;$r<$i;$r++) { // 한개씩 이전 난수와 비교루틴
if ($music[$i]==$music[$r]) {
$music[$i] = $m[mt_rand(1,$song_no)]; // 같은 난수이면 다시 난수 생성
$i--; // 이 개념을 깨닫는데 고생함... ㅡㅡ+, 상위 루틴의 루프를 한단계 다시 땡김
}
}
}
for ($k=1;$k<=$song_no;$k++) {
$list .= "$music[$k]n";
$fp=fopen(music.asx,"w");
flock($fp,2);
fwrite($fp,$list);
fclose($fp);
}
++++++++++++++++++++++++++++++++++++++++++++
페이지를 로딩할때마다 다수의 등록된 음악의 순서가 뒤섞여 다른 순서대로 재생하려고합니다.
물론 페이지가 로딩될때 여러음악이나 이미지중에서 하나를 랜덤하게 추출해서 뿌려주는건 이해가되고 실제로 활용도하고 있습니다만, 이놈도 비슷할것같은데 의외로 당췌.... ^^;;
머리가 정말 스톤인가봅니다... ㅠ..ㅠ
예를들어, m1 ~ m5의 음악이 있다고 할때 접속할때마다 아래와 같이 순서가 막 뒤섞이게하려합니다.
case1 : m1,m3,m5,m4,m2
case2 : m3,m2,m5,m1,m4
...............
rand() 또는 mt_rand()을 써서 1 ~ 5까지 임의의 숫자를 추출해서 뿌릴려고시도했습니다만, 문제는 숫자가 중복되어 나오는 경우인데 1 ~ 5가 하나씩 모두 나타나게하려니...
대략적인 소스는 아래와 같습니다. (m1~m5의 음악을 임의의 순서대로 하나씩 music.asx에 저장하여 재생하는 형식입니다)
답변해주심 무척 감사하겠습니다... (--)(__)
##########################################
$song_no = 5;
$m[1] = "mms://xxx/1.wma";
$m[2] = "mms://xxx/2.wma";
$m[3] = "mms://xxx/3.wma";
$m[4] = "mms://xxx/4.wma";
$m[5] = "mms://xxx/5.wma";
for ($i=1;$i<=$song_no;$i++) {
mt_srand ((double) microtime() * 1000000);
$music[$i] = $m[mt_rand(1,$song_no)];
}
for ($k=1;$k<=$song_no;$k++) {
$list .= "$music[$k]n";
$fp=fopen(music.asx,"w");
flock($fp,2);
fwrite($fp,$list);
fclose($fp);
}
############################################
++++++++++++++++++++++++++++++++++++++++++++
고민하다 아래와 같은 허덥한 방법으로 해결했습니다. -,.-;;
진짜 알고리즘같은 방법을 아시는 분은 리플 좀 달아주세요...
$song_no = 5;
$m[1] = "mms://xxx/1.wma";
$m[2] = "mms://xxx/2.wma";
$m[3] = "mms://xxx/3.wma";
$m[4] = "mms://xxx/4.wma";
$m[5] = "mms://xxx/5.wma";
for ($i=1;$i<=$song_no;$i++) { // 난수발생루틴
mt_srand ((double) microtime() * 1000000);
$music[$i] = $m[mt_rand(1,$song_no)];
for ($r=1;$r<$i;$r++) { // 한개씩 이전 난수와 비교루틴
if ($music[$i]==$music[$r]) {
$music[$i] = $m[mt_rand(1,$song_no)]; // 같은 난수이면 다시 난수 생성
$i--; // 이 개념을 깨닫는데 고생함... ㅡㅡ+, 상위 루틴의 루프를 한단계 다시 땡김
}
}
}
for ($k=1;$k<=$song_no;$k++) {
$list .= "$music[$k]n";
$fp=fopen(music.asx,"w");
flock($fp,2);
fwrite($fp,$list);
fclose($fp);
}
++++++++++++++++++++++++++++++++++++++++++++
댓글 5
-
캬캬캬
2002.05.08 09:42
-
골때리
2002.05.08 10:34
네... 저도 두번째 난수부터 for를 이용해 그전에 생성된 난수와 비교해보려고했는데요...
만일 동일한 난수가 나왔을 경우 다시한번 rand()를 써서 난수를 만들어야되는지... 그리고, 그렇게 생성된 난수가 또 같은 난수가 계속 반복하여 나올 경우, 어떻게 다시 for를 돌려야할지...
결국 5번의 난수 생성시 이전에 생긴 난수와 비교하는 알고리즘이 알고싶다는 얘기가 되네요...
어휴... 이렇게 바보같아서야... ㅠ..ㅠ -
골때리
2002.05.08 11:31
암튼 답변 감사합니다... -
오기
2002.05.08 11:32
저도 전에 난수 발생시 중복수를 제거하려구 열심히 머리를 굴렸다가 해결해서 올려드릴려구 했는데 소스 찾아서 올릴려니까 이미 해결하셨네요..... 같은 방법이군여.... ㅎㅎ
참고루.....
//난수발생
for ($i=0;$i<$num;$i++) { //$num개 만큼의 중복되지 않은수 발생
srand((double)microtime() * 1000000);
$rand_num = rand(0,$total_num-1); //랜덤으로 난수발생
$select_num[$i] = $rand_num; //랜덤으로 선택된수 저장
for ($j=0;$j<$i;$j++) {
if ($rand_num == $select_num[$j]) { //두 문자열이 같으면 중복된수 제거후 루프 빠져나옴
$i=$i-1;
break;
}
}
} -
Legend
2002.05.08 20:16
랜덤수 정렬보다는 비교함수를 이용한 배열정렬 방법을 사용하세요.
코드도 간단하고 중복되는 일도 없지요.
아래 두줄이면 배열m은 랜덤하게 중복없이 재배열 된 상태이므로 그냥 쓰시면 됩니다.
function Random(){return (rand()-rand()>0)? 1:-1;}
usort($m, "Random");
첫난수 이후부터는 배열에 있는 값과 비교해서 사용하시면 안될까요????