andrey Tue Oct 8 05:52:59 2002 EDT
Modified files:
/php4/ext/standard string.c
Log:
Now str_shuffle() has the randomization characteristics of shuffle().
str_shuffle() won't return anymore the randomized string and thus will be
consistent with shuffle(). Since this function is new to 4.3.0 no BC
problems.
#Thanks to Adam Trachtenberg for providing good example to check the
#permuations distribution.
Index: php4/ext/standard/string.c
diff -u php4/ext/standard/string.c:1.315 php4/ext/standard/string.c:1.316
--- php4/ext/standard/string.c:1.315 Sun Oct 6 14:39:03 2002
+++ php4/ext/standard/string.c Tue Oct 8 05:52:59 2002
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: string.c,v 1.315 2002/10/06 18:39:03 sander Exp $ */
+/* $Id: string.c,v 1.316 2002/10/08 09:52:59 andrey Exp $ */
/* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
@@ -3995,35 +3995,45 @@
/* }}} */
-static int php_string_shuffle(const void *a, const void *b TSRMLS_DC)
+static void php_string_shuffle(char *str, long len TSRMLS_DC)
{
- long rnd;
- rnd = php_rand(TSRMLS_C);
- if (rnd % 3)
- return 1;
- else if (rnd % 5)
- return 0;
- else
- return -1;
+ long n_elems, rnd_idx, n_left;
+ char temp;
+ /* The implementation is stolen from array_data_shuffle */
+ /* Thus the characteristics of the randomization are the same */
+ n_elems = len;
+
+ if (n_elems <= 1) {
+ return;
+ }
+
+ n_left = n_elems;
+
+ while (--n_left) {
+ rnd_idx = php_rand(TSRMLS_C);
+ RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX);
+ if (rnd_idx != n_left) {
+ temp = str[n_left];
+ str[n_left] = str[rnd_idx];
+ str[rnd_idx] = temp;
+ }
+ }
}
-/* {{{ proto string str_shuffle(string str)
+
+/* {{{ proto void str_shuffle(string str)
Shuffles string. One permutation of all possible is created */
PHP_FUNCTION(str_shuffle)
{
- /* Note : by using current php_string_shuffle for string */
- /* with 6 chars (6! permutations) about 2/3 of them are */
- /* computed for 6! calls for the function. So it isn't so */
- /* unique. The ratio is the same for other lengths. */
char *str;
- int i, str_len;
+ int str_len;
- i = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) ==
FAILURE) {
RETURN_FALSE;
}
- zend_qsort((void *)str, str_len, sizeof(char), php_string_shuffle TSRMLS_CC);
- RETURN_STRINGL(str, str_len, 1);
+ php_string_shuffle(str, str_len TSRMLS_CC);
+
+ return;
}
/* }}} */
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php