请问在php中的shuffle函数是如何实现的,是如何实现随机打乱数组元素的?? 请xuzning(唠叨)大哥指点,请问在哪有源吗看呢?我只要想取它的算法来参考的,谢谢你们。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 to:syre(神仙),请问你现在有这个算法在吗?可以拿来参考一下吗? http://snaps.php.net/如果你用的是linux,那么源码就在你的机器里!array.c中有PHP_FUNCTION(shuffle){... if (zend_hash_sort(Z_ARRVAL_PP(array), (sort_func_t)php_mergesort, array_data_shuffle, 1) == FAILURE) { RETURN_FALSE; } RETURN_TRUE;}static int array_data_shuffle(const void *a, const void*b) { return (php_rand() % 2) ? 1 : -1;}mergesort.c中有int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *)){ register unsigned int i; register int sense; int big, iflag; register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; u_char *list2, *list1, *p2, *p, *last, **p1; if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ errno = EINVAL; return (-1); } if (nmemb == 0) return (0); /* * XXX * Stupid subtraction for the Cray. */ iflag = 0; if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE)) iflag = 1; if ((list2 = malloc(nmemb * size + PSIZE)) == NULL) return (-1); list1 = base; setup(list1, list2, nmemb, size, cmp); last = list2 + nmemb * size; i = big = 0; while (*EVAL(list2) != last) { l2 = list1; p1 = EVAL(list1); for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) { p2 = *EVAL(p2); f1 = l2; f2 = l1 = list1 + (p2 - list2); if (p2 != last) p2 = *EVAL(p2); l2 = list1 + (p2 - list2); while (f1 < l1 && f2 < l2) { if ((*cmp)(f1, f2) <= 0) { q = f2; b = f1, t = l1; sense = -1; } else { q = f1; b = f2, t = l2; sense = 0; } if (!big) { /* here i = 0 */ while ((b += size) < t && cmp(q, b) >sense) if (++i == 6) { big = 1; goto EXPONENTIAL; } } else {EXPONENTIAL: for (i = size; ; i <<= 1) if ((p = (b + i)) >= t) { if ((p = t - size) > b && (*cmp)(q, p) <= sense) t = p; else b = p; break; } else if ((*cmp)(q, p) <= sense) { t = p; if (i == size) big = 0; goto FASTCASE; } else b = p; while (t > b+size) { i = (((t - b) / size) >> 1) * size; if ((*cmp)(q, p = b + i) <= sense) t = p; else b = p; } goto COPY;FASTCASE: while (i > size) if ((*cmp)(q, p = b + (i >>= 1)) <= sense) t = p; else b = p;COPY: b = t; } i = size; if (q == f1) { if (iflag) { ICOPY_LIST(f2, tp2, b); ICOPY_ELT(f1, tp2, i); } else { CCOPY_LIST(f2, tp2, b); CCOPY_ELT(f1, tp2, i); } } else { if (iflag) { ICOPY_LIST(f1, tp2, b); ICOPY_ELT(f2, tp2, i); } else { CCOPY_LIST(f1, tp2, b); CCOPY_ELT(f2, tp2, i); } } } if (f2 < l2) { if (iflag) ICOPY_LIST(f2, tp2, l2); else CCOPY_LIST(f2, tp2, l2); } else if (f1 < l1) { if (iflag) ICOPY_LIST(f1, tp2, l1); else CCOPY_LIST(f1, tp2, l1); } *p1 = l2; } tp2 = list1; /* swap list1, list2 */ list1 = list2; list2 = tp2; last = list2 + nmemb*size; } if (base == list2) { memmove(list2, list1, nmemb*size); list2 = list1; } free(list2); return (0);}其他的自己找找吧 $a=array(0,1,2,3,4,5,6,7,8,9);$count=count($a);for($i=0;$i<$count;$i++){$t=$a[$i];$p=rand(0,$count);$a[$i]=$a[$p];$a[$p]=$t;}print_r($a);我的机器出了问题,不能调试了。因该没有什么问题 谢谢你们了,我本来只是想看看它的算法的,但是太复杂了,很多没有编译的函数都不知它是来之何处,更不清楚。请问你们有没有听说过“洗牌算法”呢?,php中的shuffle函数也属于这个算法,我想用最简单的语句来实现,在javascript中,来打乱数组的内容,使得一个在线播放器实现“随机播放”的效果。。谢谢。。 这样啊,看看这个<SCRIPT LANGUAGE="JavaScript"><!--var n=26;var ar=[];for (var i=0;i<n+n;i++) ar[i]=i+1;function swap(){ var a1=[],a2=[]; for (var i=0;i<n;i++){ a1[i]=ar[i]; a2[i]=ar[i+n] } for (var i=0;i<n;i++){ ar[i+i]=a1[i]; ar[i+i+1]=a2[i]; }}document.write("初始状态:<br/>"+ar+"<br/>");for (var i=1;ar[1]!=2||i==1;i++){ swap(); document.write("第"+i+"遍: <br/>"+ar+"<br/>");}//--></SCRIPT> 想了一下,这样可能简单些<script>ar = new Array(1,2,3,4,5,6,7,8);ar = ar.sort(foo);alert(ar);function foo(a,b) { return (Math.random(100)*10)%2 ? 1 : -1;}</script> 请问xuzuning(唠叨) ,可以解释一下函数foo(a,b)的用意吗?我看函数foo(a,b)它是始终返回“1"的,可以说说吗? $array1[rand(count($array1))];这样成不? function foo(a,b) { return (Math.random()*10)%2 ? 1 : -1;}1、不会始终返回12、这是sort方法的回调函数,参数a,b由sort方法给出。由您决定返回值:0 相等;1 a.b;-1 a<b在这里没有用到这两个参数 请问xuzuning(唠叨),可是我怎么每一次调用这个函数都得到同一样的结果呢?你说a,b参数现在没有用到,它不是肯定返回“1"吗? 请问xuzuning(唠叨),在javascript中,rand()函数有参数的吗?你在rand()中加入了100为参数有什么作用呢?function foo(a,b) { return (Math.random(100)*10)%2 ? 1 : -1;} 关于php模拟登陆的问题。。 哭死我了。。求高手帮忙了!跪求了!!! 很奇怪的问题:只能输英文,不能输中文 本人PHP一年,5年左右程序员经验。希望能有高人加为好友。沙发着分! 如何根据选项显示数据 PHP从数据库读取数据是否有限制 200元出售整套OA代码 有无人写过生成图型的类呀? 我在用这个类时发现不能输出图型呀,请指教? 这也能出错?!!!!! 怎么用php在linux主机建立两层目录???……再谈php程序建立目录的问题 再提一问,这个错误是什么? 如何得到php当前执行的页面文件名
如果你用的是linux,那么源码就在你的机器里!array.c中有
PHP_FUNCTION(shuffle)
{
...
if (zend_hash_sort(Z_ARRVAL_PP(array), (sort_func_t)php_mergesort, array_data_shuffle, 1) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
}static int array_data_shuffle(const void *a, const void*b) {
return (php_rand() % 2) ? 1 : -1;
}mergesort.c中有
int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *))
{
register unsigned int i;
register int sense;
int big, iflag;
register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2;
u_char *list2, *list1, *p2, *p, *last, **p1; if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */
errno = EINVAL;
return (-1);
} if (nmemb == 0)
return (0); /*
* XXX
* Stupid subtraction for the Cray.
*/
iflag = 0;
if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
iflag = 1; if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
return (-1); list1 = base;
setup(list1, list2, nmemb, size, cmp);
last = list2 + nmemb * size;
i = big = 0;
while (*EVAL(list2) != last) {
l2 = list1;
p1 = EVAL(list1);
for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) {
p2 = *EVAL(p2);
f1 = l2;
f2 = l1 = list1 + (p2 - list2);
if (p2 != last)
p2 = *EVAL(p2);
l2 = list1 + (p2 - list2);
while (f1 < l1 && f2 < l2) {
if ((*cmp)(f1, f2) <= 0) {
q = f2;
b = f1, t = l1;
sense = -1;
} else {
q = f1;
b = f2, t = l2;
sense = 0;
}
if (!big) { /* here i = 0 */
while ((b += size) < t && cmp(q, b) >sense)
if (++i == 6) {
big = 1;
goto EXPONENTIAL;
}
} else {
EXPONENTIAL: for (i = size; ; i <<= 1)
if ((p = (b + i)) >= t) {
if ((p = t - size) > b &&
(*cmp)(q, p) <= sense)
t = p;
else
b = p;
break;
} else if ((*cmp)(q, p) <= sense) {
t = p;
if (i == size)
big = 0;
goto FASTCASE;
} else
b = p;
while (t > b+size) {
i = (((t - b) / size) >> 1) * size;
if ((*cmp)(q, p = b + i) <= sense)
t = p;
else
b = p;
}
goto COPY;
FASTCASE: while (i > size)
if ((*cmp)(q,
p = b + (i >>= 1)) <= sense)
t = p;
else
b = p;
COPY: b = t;
}
i = size;
if (q == f1) {
if (iflag) {
ICOPY_LIST(f2, tp2, b);
ICOPY_ELT(f1, tp2, i);
} else {
CCOPY_LIST(f2, tp2, b);
CCOPY_ELT(f1, tp2, i);
}
} else {
if (iflag) {
ICOPY_LIST(f1, tp2, b);
ICOPY_ELT(f2, tp2, i);
} else {
CCOPY_LIST(f1, tp2, b);
CCOPY_ELT(f2, tp2, i);
}
}
}
if (f2 < l2) {
if (iflag)
ICOPY_LIST(f2, tp2, l2);
else
CCOPY_LIST(f2, tp2, l2);
} else if (f1 < l1) {
if (iflag)
ICOPY_LIST(f1, tp2, l1);
else
CCOPY_LIST(f1, tp2, l1);
}
*p1 = l2;
}
tp2 = list1; /* swap list1, list2 */
list1 = list2;
list2 = tp2;
last = list2 + nmemb*size;
}
if (base == list2) {
memmove(list2, list1, nmemb*size);
list2 = list1;
}
free(list2);
return (0);
}
其他的自己找找吧
$count=count($a);
for($i=0;$i<$count;$i++){
$t=$a[$i];
$p=rand(0,$count);
$a[$i]=$a[$p];
$a[$p]=$t;
}
print_r($a);
我的机器出了问题,不能调试了。因该没有什么问题
<SCRIPT LANGUAGE="JavaScript">
<!--
var n=26;
var ar=[];
for (var i=0;i<n+n;i++) ar[i]=i+1;function swap(){
var a1=[],a2=[];
for (var i=0;i<n;i++){
a1[i]=ar[i];
a2[i]=ar[i+n]
}
for (var i=0;i<n;i++){
ar[i+i]=a1[i];
ar[i+i+1]=a2[i];
}
}
document.write("初始状态:<br/>"+ar+"<br/>");
for (var i=1;ar[1]!=2||i==1;i++){
swap();
document.write("第"+i+"遍: <br/>"+ar+"<br/>");
}
//-->
</SCRIPT>
<script>
ar = new Array(1,2,3,4,5,6,7,8);
ar = ar.sort(foo);
alert(ar);
function foo(a,b) {
return (Math.random(100)*10)%2 ? 1 : -1;
}
</script>
这样成不?
return (Math.random()*10)%2 ? 1 : -1;
}1、不会始终返回1
2、这是sort方法的回调函数,参数a,b由sort方法给出。由您决定返回值:0 相等;1 a.b;-1 a<b
在这里没有用到这两个参数
你说a,b参数现在没有用到,它不是肯定返回“1"吗?
function foo(a,b) {
return (Math.random(100)*10)%2 ? 1 : -1;
}