I want only 6 random numbers [length = 6] from 0,1,2,3,4,5,6,7,8,9 in php function without duplicates.
This is my code
$a = mt_rand(1,9999999999); //because I need from 1 to 9999999999 of(0,1,2,3,4,5,6,7,8,9)
for ($i = 0; $i<6; $i++)
{
$a .= mt_rand(0,9);
}
I am not sure my code is good solution or not
How I can do it?
Try this code.
function GenerateRandom($min, $max, $range) {
$numbers = range($min, $max);
shuffle($numbers);
return array_slice($numbers, 0, $range);
}
print_r( GenerateRandom(0,25,6) );
Hope this helps.
If your source array is rather big, you may save some memory by only fetching what you need:
$a = range(0, 9);
for ($i = 0, $n = count($a); $i < 6 && --$n; ++$i) {
$r = mt_rand(0, $n);
if ($r != $n) {
$tmp = $a[$n];
$a[$n] = $a[$r];
$a[$r] = $tmp;
}
}
echo join(',', array_slice($a, -6));
I'm coining the term "Partial Knuth Shuffle" for this.
Related
I need to get 50 random numbers out of range 1-100 without repeating. The current way i do is :
$array = array();
while (count($array) <= 50) {
$temp = random_int(1,100);
if (!in_array($temp, $array))
$array[] = $temp;
}
However, the looping is too many because I need to generate for more than 100,000 times.
Is there other ways that I can get a 50 random non-repeating numbers without looping ?
For example:
$number= range(1,100);
$array = array_slice(shuffle($number),0,50);
I can't use shuffle because it uses pseudo random number.
Is there other ways to achieve what I need, or ways that could shorten time.
pre fill a array of numbers and pick from them, and then remove it.
it prevents the unnecessary random generations you have
$numbers = [];
for ($i = 1; $i <= 100; $i++) {
$numbers[] = $i;
}
$randomNumbers = [];
for ($i = 1; $i <= 50; $i++) {
$r = rand(0, count($numbers) - 1);
$randomNumbers[] = $numbers[$r];
array_splice($numbers, $r, 1);
}
This would be my approach:
This gives you 50 numbers in any case, and they are defenitely different from each other. PLUS: you dont have to prefill some other array:
$start = microtime(true);
for($i = 0; $i <= 100000; $i++){
$arr = [];
while(sizeof($arr) < 50){
$num = rand(1, 100);
$arr[$num] = $num;
}
if(array_unique($arr) !== $arr || sizeof($arr) !== 50 ){
print("FAIL");
}
//print(array_unique($arr) == $arr ? "true" : "false");print("<br>");
//print(sizeof($arr));print("<br>");
//print_r(array_count_values ($arr));print("<br>");
//print_r($arr);print("<br>");
}
$time_elapsed_secs = microtime(true) - $start;
print($time_elapsed_secs);print("<br>");
Running this 100000 times takes about 0.4sec for me.
The actual generation is done in this part:
$arr = [];
while(sizeof($arr) < 50){
$num = rand(1, 100);
$arr[$num] = $num;
}
We can do in 2 steps:
$x = 0;
$arr = [];
while($x < 50){
$tmp = rand(1, 100);
if(!in_array($tmp, $arr)){
$arr[] = $tmp;
$x++;
}
}
This question already has answers here:
PHP get the item in an array that has the most duplicates
(2 answers)
Closed 1 year ago.
I have an array of numbers like this:
$array = array(1,1,1,4,3,1);
How do I get the count of most repeated value?
This should work:
$count=array_count_values($array);//Counts the values in the array, returns associatve array
arsort($count);//Sort it from highest to lowest
$keys=array_keys($count);//Split the array so we can find the most occuring key
echo "The most occuring value is $keys[0][1] with $keys[0][0] occurences."
I think array_count_values function can be useful to you. Look at this manual for details : http://php.net/manual/en/function.array-count-values.php
You can count the number of occurrences of values in an array with array_count_values:
$counts = array_count_values($array);
Then just do a reverse sort on the counts:
arsort($counts);
Then check the top value to get your mode.
$mode = key($counts);
If your array contains strings or integers only you can use array_count_values and arsort:
$array = array(1, 1, 1, 4, 3, 1);
$counts = array_count_values($array);
arsort($counts);
That would leave the most used element as the first one of $counts. You can get the count amount and value afterwards.
It is important to note that if there are several elements with the same amount of occurrences in the original array I can't say for sure which one you will get. Everything depends on the implementations of array_count_values and arsort. You will need to thoroughly test this to prevent bugs afterwards if you need any particular one, don't make any assumptions.
If you need any particular one, you'd may be better off not using arsort and write the reduction loop yourself.
$array = array(1, 1, 1, 4, 3, 1);
/* Our return values, with some useless defaults */
$max = 0;
$max_item = $array[0];
$counts = array_count_values($array);
foreach ($counts as $value => $amount) {
if ($amount > $max) {
$max = $amount;
$max_item = $value;
}
}
After the foreach loop, $max_item contains the last item that appears the most in the original array as long as array_count_values returns the elements in the order they are found (which appears to be the case based on the example of the documentation). You can get the first item to appear the most in your original array by using a non-strict comparison ($amount >= $max instead of $amount > $max).
You could even get all elements tied for the maximum amount of occurrences this way:
$array = array(1, 1, 1, 4, 3, 1);
/* Our return values */
$max = 0;
$max_items = array();
$counts = array_count_values($array);
foreach ($counts as $value => $amount) {
if ($amount > $max) {
$max = $amount;
$max_items = array($value);
} elif ($amount = $max) {
$max_items[] = $value;
}
}
$vals = array_count_values($arr);
asort($vals);
//you may need this end($vals);
echo key($vals);
I cant remember if asort sorts asc or desc by default, you can see the comment in the code.
<?php
$arrrand = '$arr = array(';
for ($i = 0; $i < 100000; $i++)
{
$arrrand .= rand(0, 1000) . ',';
}
$arrrand = substr($arrrand, 0, -1);
$arrrand .= ');';
eval($arrrand);
$start1 = microtime();
$count = array_count_values($arr);
$end1 = microtime();
echo $end1 - $start1;
echo '<br>';
$start2 = microtime();
$tmparr = array();
foreach ($arr as $key => $value);
{
if (isset($tmparr[$value]))
{
$tmparr[$value]++;
} else
{
$tmparr[$value] = 1;
}
}
$end2 = microtime();
echo $end2 - $start2;
Here check both solutions:
1 by array_count_values()
and one by hand.
<?php
$input = array(1,2,2,2,8,9);
$output = array();
$maxElement = 0;
for($i=0;$i<count($input);$i++) {
$count = 0;
for ($j = 0; $j < count($input); $j++) {
if ($input[$i] == $input[$j]) {
$count++;
}
}
if($count>$maxElement){
$maxElement = $count;
$a = $input[$i];
}
}
echo $a.' -> '.$maxElement;
The output will be 2 -> 3
$arrays = array(1, 2, 2, 2, 3, 1); // sample array
$count=array_count_values($arrays); // getting repeated value with count
asort($count); // sorting array
$key=key($count);
echo $arrays[$key]; // get most repeated value from array
String S;
Scanner in = new Scanner(System.in);
System.out.println("Enter the String: ");
S = in.nextLine();
int count =1;
int max = 1;
char maxChar=S.charAt(0);
for(int i=1; i <S.length(); i++)
{
count = S.charAt(i) == S.charAt(i - 1) ? (count + 1):1;
if(count > max)
{
max = count;
maxChar = S.charAt(i);
}
}
System.out.println("Longest run: "+max+", for the character "+maxChar);
here is the solution
class TestClass {
public $keyVal;
public $keyPlace = 0;
//put your code here
public function maxused_num($array) {
$temp = array();
$tempval = array();
$r = 0;
for ($i = 0; $i <= count($array) - 1; $i++) {
$r = 0;
for ($j = 0; $j <= count($array) - 1; $j++) {
if ($array[$i] == $array[$j]) {
$r = $r + 1;
}
}
$tempval[$i] = $r;
$temp[$i] = $array[$i];
}
//fetch max value
$max = 0;
for ($i = 0; $i <= count($tempval) - 1; $i++) {
if ($tempval[$i] > $max) {
$max = $tempval[$i];
}
}
//get value
for ($i = 0; $i <= count($tempval) - 1; $i++) {
if ($tempval[$i] == $max) {
$this->keyVal = $tempval[$i];
$this->keyPlace = $i;
break;
}
}
// 1.place holder on array $this->keyPlace;
// 2.number of reapeats $this->keyVal;
return $array[$this->keyPlace];
}
}
$catch = new TestClass();
$array = array(1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 1, 2, 3, 1, 1, 2, 5, 7, 1, 9, 0, 11, 22, 1, 1, 22, 22, 35, 66, 1, 1, 1);
echo $catch->maxused_num($array);
I have tried to write a basic merge sort in PHP involving a small array, yet the problem is it takes about a minute or so to execute, and returns:
Fatal error: Allowed memory size of 536870912 bytes exhausted (tried
to allocate 35 bytes) in /Users/web/www/merge.php on line 39
Does anyone have an idea where the code might be going wrong (if at all)? I've been staring at this for a good hour now.
<?php
$array = array(8,1,2,5,6,7);
print_array($array);
merge_sort($array);
print_array($array);
function merge_sort(&$list){
if( count($list) <= 1 ){
return $list;
}
$left = array();
$right = array();
$middle = (int) ( count($list)/2 );
// Make left
for( $i=0; $i < $middle; $i++ ){
$left[] = $list[$i];
}
// Make right
for( $i = $middle; $i < count($list); $i++ ){
$right[] = $list[$i];
}
// Merge sort left & right
merge_sort($left);
merge_sort($right);
// Merge left & right
return merge($left, $right);
}
function merge(&$left, &$right){
$result = array();
while(count($left) > 0 || count(right) > 0){
if(count($left) > 0 && count(right) > 0){
if($left[0] <= $right[0]){
$result[] = array_shift($left);
} else {
$result[] = array_shift($right);
}
} elseif (count($left) > 0){
$result[] = array_shift($left);
} elseif (count($right) > 0){
$result[] = array_shift($right);
}
}
print_array($result);exit;
return $result;
}
function print_array($array){
echo "<pre>";
print_r($array);
echo "<br/>";
echo "</pre>";
}
?>
In your merge function, you call count on right instead of $right. PHP assumes this is a string constant (at least in 5.3.9) and when casted into an array that always has one element. So count(right) is always one, and you never exit the first merge.
Try this approach. Instead of shifting it, slice.
Also, for in while loop for the merge function, you need to do an and && comparison instead
of ||
function mergeSort($array)
{
if(count($array) == 1 )
{
return $array;
}
$mid = count($array) / 2;
$left = array_slice($array, 0, $mid);
$right = array_slice($array, $mid);
$left = mergeSort($left);
$right = mergeSort($right);
return merge($left, $right);
}
function merge($left, $right)
{
$res = array();
while (count($left) > 0 && count($right) > 0)
{
if($left[0] > $right[0])
{
$res[] = $right[0];
$right = array_slice($right , 1);
}
else
{
$res[] = $left[0];
$left = array_slice($left, 1);
}
}
while (count($left) > 0)
{
$res[] = $left[0];
$left = array_slice($left, 1);
}
while (count($right) > 0)
{
$res[] = $right[0];
$right = array_slice($right, 1);
}
return $res;
}
Have a look at this, the algorithm is already implemented, using array_push and array splice instead of just array_shift.
http://www.codecodex.com/wiki/Merge_sort#PHP
I implement merge sort this way
function mergeSort($Array)
{
$len = count($Array);
if($len==1){
return $Array;
}
$mid = (int)$len / 2;
$left = mergeSort(array_slice($Array, 0, $mid));
$right = mergeSort(array_slice($Array, $mid));
return merge($left, $right);
}
function merge($left, $right)
{
$combined = [];
$totalLeft = count($left);
$totalRight = count($right);
$rightIndex = $leftIndex=0;
while ($leftIndex < $totalLeft && $rightIndex < $totalRight) {
if ($left[$leftIndex] > $right[$rightIndex]) {
$combined[]=$right[$rightIndex];
$rightIndex++;
}else {
$combined[] =$left[$leftIndex];
$leftIndex++;
}
}
while($leftIndex<$totalLeft){
$combined[]=$left[$leftIndex];
$leftIndex++;
}
while ($rightIndex<$totalRight){
$combined[] =$right[$rightIndex];
$rightIndex++;
}
return $combined;
}
Here is the class in PHP to implement the Merge Sort -
<?php
class mergeSort{
public $arr;
public function __construct($arr){
$this->arr = $arr;
}
public function mSort($l,$r){
if($l===null || $r===null){
return false;
}
if ($l < $r)
{
// Same as ($l+$r)/2, but avoids overflow for large $l and $r
$m = $l+floor(($r-$l)/2);
// Sort first and second halves
$this->mSort($l, $m);
$this->mSort($m+1, $r);
$this->merge($l, $m, $r);
}
}
// Merges two subarrays of $this->arr[]. First subarray is $this->arr[$l..$m]. Second subarray is $this->arr[$m+1..$r]
public function merge($l, $m, $r)
{
if($l===null || $m===null || $r===null){
return false;
}
$n1 = $m - $l + 1;
$n2 = $r - $m;
/* create temp arrays */
$L=array();
$R=array();
/* Copy data to temp arrays $L[] and $R[] */
for ($i = 0; $i < $n1; $i++)
$L[$i] = $this->arr[$l + $i];
for ($j = 0; $j < $n2; $j++)
$R[$j] = $this->arr[$m + 1+ $j];
/* Merge the temp arrays back into $this->arr[$l..$r]*/
$i = 0; // Initial index of first subarray
$j = 0; // Initial index of second subarray
$k = $l; // Initial index of merged subarray
while ($i < $n1 && $j < $n2)
{
if($L[$i] <= $R[$j])
{
$this->arr[$k] = $L[$i];
$i++;
}
else
{
$this->arr[$k] = $R[$j];
$j++;
}
$k++;
}
/* Copy the remaining elements of $L[], if there are any */
while($i < $n1)
{
$this->arr[$k] = $L[$i];
$i++;
$k++;
}
/* Copy the remaining elements of $R[], if there are any */
while($j < $n2)
{
$this->arr[$k] = $R[$j];
$j++;
$k++;
}
}
}
$arr = array(38, 27, 43, 5, 9, 91, 12);
$obj = new mergeSort($arr);
$obj->mSort(0,6);
print_r($obj->arr);
?>
I was looking for a optimized Mergesort algorithm in PHP. There are 5 algorithms in the answers, so I tested those, and mine too. Using PHP 7.2.7, these are the times:
Sorting 1000 random numbers:
Avanche 1 0.0396 seconds
Avanche 2 0.0347 seconds
Kartik 0.0291 seconds
Kripa 0.0282 seconds
Samuel 0.0247 seconds
Mine 0.0144 seconds
Sorting 10 random numbers:
Avanche 1 0.000222 seconds
Kartik 0.000216 seconds
Kripa 0.000159 seconds
Avanche 2 0.000144 seconds
Samuel 0.000128 seconds
Mine 0.000098 seconds
So, although I encourage to whom read it to make it faster (that was I was looking for, and I believe it can be done), I let you my implementation too, cause seems to be faster than the other answers:
//This function needs start and end limits
function mergeSortRec(&$a,$start,$end){
if($start<$end){
$center=($start+$end)>>1; //Binary right shift is like divide by 2
mergeSortRec($a, $start, $center);
mergeSortRec($a, $center+1, $end);
//Mixing the 2 halfs
$aux=array();
$left=$start; $right=$center;
//Main loop
while($left<$center && $right<=$end){
if($a[$left]<$a[$right]){
$aux[]=$a[$left++];
}else{
$aux[]=$a[$right++];
}
}
//Copy the rest of the first half
while($left<$center) $aux[]=$a[$left++];
//Copy the rest of the second half
while($right<=$end) $aux[]=$a[$right++];
//Copy the aux array to the main array
foreach($aux as $v) $a[$start++]=$v;
}
}
//This is the function easier to call
function mergeSort(&$a) {
mergeSortRec($a,0,count($a)-1);
}
If you post a new answer, let me a comment to test it and add it.
Edit: I did some new optimizations, for those looking for a better implementation.
Your merge sort accepts a list by reference
function merge_sort(&$list)
So you need to assign it the new merged and sorted list. So instead of
return merge($left, $right);
do
$list = $this->merge($left, $right);
That should do it, just remove the exit and fix the count variable
MergeSort in PHP
<?php
class Solution
{
function mergeSort(&$arr)
{
if(count($arr) > 1) {
$mid = floor(count($arr)/2);
$left = array_slice($arr, 0, $mid);
$right = array_slice($arr, $mid);
$this->mergeSort($left);
$this->mergeSort($right);
// Merge the results.
$i = $j = $k = 0;
while(($i < count($left)) && ($j < count($right))) {
if($left[$i] < $right[$j]) {
$arr[$k] = $left[$i];
$i++;
} else {
$arr[$k] = $right[$j];
$j++;
}
$k++;
}
while($i < count($left)) {
$arr[$k] = $left[$i];
$i++;
$k++;
}
while($j < count($right)) {
$arr[$k] = $right[$j];
$j++;
$k++;
}
}
}
}
$s = new Solution();
$tmp = [12, 7, 11, 13, 5, 6, 7];
$s->mergeSort($tmp);
print_r($tmp);
I want to get the highest value of my array.
This are the two ways when I'm working with php functions.
$a = array(1,125,1068);
1. $value = max($a);
print_r ($value);
2. asort($a);
$value = end($a);
print_r ($value);
I just couldn't figure out how to get the highest value when using loops.
You do it like this:
$highest = 0;
//if you have negative values: $highest = min($a);
foreach($a as $item){
if ($item > $highest){
$highest = $item;
}
}
Without using the max() function, you can do something like
<?php
$a = array(1,125,1068)
$max = $a[0];
for ($i = 1; $i <count($a); $i++) {
if ($a[$i] > $max) {
$max = $a[$i];
}
}
echo $max;
?>
max()
http://php.net/manual/en/function.max.php
$dd = array(50, -25, -5, 80, -40, -152, -45, 28, -455, 100, 98, -455);
$curr = '';
$max = $dd[0];
for($i = 0; $i < count($dd); $i++) {
$curr = $dd[$i];
if($curr >= $max) {
$max = $curr;
}
}
How could I echo 5 elements randomly from an array of about 20?
Thanks.
Does this work?
$values = array_rand($input, 5);
Or, as a more flexible function
function randomValues($input, $num = 5) {
return array_rand($input, $num);
}
//usage
$array = range('a', 'z');
//prints 5 random characters from the alphabet
print_R(randomValues($array));
for($i=0; $i++; $i < 5)
{
echo $array[rand(0, count($array)-1);
}
or
for($i=0; $i++; $i < 5)
{
echo array_rand($array);
}
or
array_map("echo", array_rand($array, 5));
$n = number of random numbers to return in the array
$min = minimum number
$max = maximum number
function uniqueRand($n, $min = 0, $max = null)
{
if($max === null)
$max = getrandmax();
$array = range($min, $max);
$return = array();
$keys = array_rand($array, $n);
foreach($keys as $key)
$return[] = $array[$key];
return $return;
}
$randNums = uniqueRand(5, 0, count($array)-1);
for($i=0; $i++; $i < 5)
{
echo $array[$randNums[i]);
}