Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, May 7, 2016

How can I determine two numbers that are more close than others in an array

How can I determine two numbers that are more close than others in an array


I have this array:

$arr = array (20, 1, 5, 10, 7, 16);  

I would like to get 5 and 7. Because these are more close to each other than other items. In other word the difference between them is the lowest number:

7 - 5 = 2 // 2 is lowest number as the difference between all array's items  

How can I do that?


$keep = $arr[0];  $diff = $arr[1] - $arr[0];  foreach ($arr as $item) {      if ( ($keep - $item) < $diff && $keep != $item ) {          $diff = $item;      }  }  

My code is incomplete, Because it just compares first item with other items.

Answer by Sachin for How can I determine two numbers that are more close than others in an array


PHP usort is used here, as a note it is implemented with quicksort.

$temp ==> Temporary array to store the two values and its differences while looping
$temp = [arr[$i] , arr[$j] , arr[$i]-arr[$j] ]

   $arr = array (20, 1, 5, 10, 7, 16);     $temp=array();           for ($i = 0; $i < count($arr)-1; $i++)         {          $diff=0;          for ($j = $i+1; ($j < count($arr) && $i!=$j); $j++)          {              $diff=abs($arr[$i]-$arr[$j]);     //finding difference &taking absolute               $temp[] = array($arr[$i],$arr[$j], $diff);           }      }      usort($temp,function ($a, $b) { return $b[2] < $a[2]; });//sort `$temp[]` in ascending order according to the difference value      list($x,$y,$d) = $temp[0];   //the first row of `$temp` contains values with the diff. is lowest                                   //and the values is stored to `$x` & `$y` and there difference in `$d`      echo "Related Values are $x and $y by $d";   

Check results here http://ideone.com/pZ329m

Working

 20  1    5  10   7  16          //inner loop -----------------------                         |   |    |   |   |   |  $temp[]=[[20,1,19],[20,5,15],[20,10,10],...//$i=0 |// `20` is compared values from 1 onwards and the values and differences are stored in `$temp[]`   |___|____|___|___|___|  //(eg., $temp=[20,1,|20-1|])        //$j=1,2,3,4,5?       |    |   |   |   |          [1,5,4],[1,10,9],...               //$i=1 | `1` is compared with values from 5 onwards       |____|___|___|___|                                     //$j=2,3,4,5   ?outer loop            |   |   |   |          [5,10,5],[5,7,2],...               //$i=2 | `5` is compared with values from 10 onwards            |___|___|___|                                     //$j=3,4,5     ?                |   |   |          [10,7,3],[10,16,6]                 //$i=3 | `10` is compared with values from 7 onwards                |___|___|                                     //$j=4,5       ?                    |   |          [7,16,9]]                          //$i=4 |`7` is compared with final value `16`                    |___|                                     //$j=5         ?  

After getting $temp[] , it's sorted in ascending order according to the differences .
Then the first row of $temp[] gives our desired result .


Whats inside $temp[]

 Array  (      [0] => Array          (              [0] => 7              [1] => 5              [2] => 2          )        [1] => Array          (              [0] => 7              [1] => 10              [2] => 3          )        [2] => Array          (              [0] => 16              [1] => 20              [2] => 4          )        [3] => Array          (              [0] => 5              [1] => 1              [2] => 4          )        [4] => Array          (              [0] => 10              [1] => 5              [2] => 5          )        [5] => Array          (              [0] => 16              [1] => 10              [2] => 6          )        [6] => Array          (              [0] => 7              [1] => 1              [2] => 6          )        [7] => Array          (              [0] => 16              [1] => 7              [2] => 9          )        [8] => Array          (              [0] => 10              [1] => 1              [2] => 9          )        [9] => Array          (              [0] => 10              [1] => 20              [2] => 10          )        [10] => Array          (              [0] => 16              [1] => 5              [2] => 11          )        [11] => Array          (              [0] => 7              [1] => 20              [2] => 13          )        [12] => Array          (              [0] => 5              [1] => 20              [2] => 15          )        [13] => Array          (              [0] => 16              [1] => 1              [2] => 15          )        [14] => Array          (              [0] => 1              [1] => 20              [2] => 19          )    )  

Answer by Frayne Konok for How can I determine two numbers that are more close than others in an array


As i comment to use 2 loop and a condition, i did the same thing. Just check it out and let me know.

$arr = array (20, 1, 5, 10, 7, 16);    $c = count($arr);  $ld = max($arr);  for($i = 0; $i < $c; $i++){      for($j = $i+1; $j < $c; $j++){          $abs = abs($arr[$i]-$arr[$j]);          if($abs < $ld)              $ld = $abs;      }  }  echo $ld; //2  

if you need to know which two value has the difference then it is possible, just store them inside the if condition.

Answer by MarcoS for How can I determine two numbers that are more close than others in an array


$arr = array(20, 1, 5, 10, 7, 16);    $min = max($arr);  $closest = array();  foreach ($arr as $i) {    foreach ($arr as $j) {      if ($i != $j) {        $diff = abs($i - $j);        if ($min > $diff) {          $min = $diff;          $closest[0] = $i;          $closest[1] = $j;        }      }    }  }    print "The two closest numbers are " . $closest[0] . " and " . $closest[1];  

Answer by Leo Turi for How can I determine two numbers that are more close than others in an array


Well, quick and dirty... two loops, one condition

//$arr = array (20, 1, 5, 10, 7, 16); gives 5 and 7  $arr = array (-32,-15,4,6,-14,613,4,63,6,4);  $diff = INF;  foreach ($arr as $item0) {      foreach ($arr as $item1) {          $localdiff = abs($item0 - $item1);          if ( $localdiff > 0 && $localdiff < $diff ) {              $diff = $localdiff;              $keep0 = $item0;              $keep1 = $item1;          }      }  }    echo "Smallest distance was $diff, between $keep0 and $keep1";  

Check it out on http://ideone.com/WdWOcb

Answer by Brijal Savaliya for How can I determine two numbers that are more close than others in an array


use this

 $arr = array (20, 1, 5, 10, 7, 16);    $temp = array();  foreach ($arr as $item1) {      foreach ($arr as $item2) {          $aV = abs($item1-$item2);          if(!in_array($aV, $temp) && $aV!=0)              $temp[$item1."-".$item2] =$aV;      }       }  $closest = array_keys($temp,min($temp));  list($first,$explode,$second) = $closest[0];  print "The two closest numbers are " . $first . " and " . $second;  

Answer by Rizier123 for How can I determine two numbers that are more close than others in an array


Explanation

So to get the two numbers in an array which are the closest to each other you have to compare each value with each other value. But you don't have to compare them with themselfs and to the previous ones which you already compared.

To calculate how many comparison you have to do you can use the binomial coefficient:

(n)            n!  (k)   ?   ?????????????            k! * (n - k)!  

Where n is the total amount of elements and k how many you pick

And in your example this would mean:

n = 6 //Array elements  k = 2 //Two values which you compare         6!                  720  ?????????????   ?   ?????????????   = 15 comparison  2! * (6 - 2)!          2  *  24  

Visualized

20 , 1 , 5 , 10 , 7 , 16  //Array values  ?    ?   ?   ?    ?   ?  ???????????????????????  //20 compared to all values, except itself       ?   ?   ?    ?   ?       ??????????????????  //1  compared to all values, except itself + [20]           ?   ?    ?   ?           ??????????????  //5  compared to all values, except itself + [20, 1]               ?    ?   ?               ??????????  //10 compared to all values, except itself + [20, 1, 5]                    ?   ?                    ?????  //7  compared to all values, except itself + [20, 1, 5, 10]                             //16 compared to all values, except itself + [20, 1, 5, 10, 7]  

Now to do this in code we need 2 loops to loop over the entire array for each value of the first loop. But as we already said we can ignore the value itself and the previous values, so for this we use 2 for loops and set the key, for the inner loop, to be the outer key + 1.

for($key = 0, $length = count($arr); $key < $length; $key++){                for($innerKey = $key + 1; $innerKey < $length; $innerKey++){        //? Skipping the previous values and the value itself          }                 }  

In the inner loop itself we just need to access the current value of the outer loop and get the difference compared to the value of the inner loop. That this also works with negative numbers we just wrap it into a abs() call to make the difference always positive.

Then we just check if the difference is smaller than the smallest difference which we already found, saved in $nearest. (We initialized $nearest by the difference of the biggest and smallest value of the array + 1):

if( ($diff = abs($arr[$keys[$key]] - $arr[$keys[$innerKey]])) < $nearest)            

If the difference is smaller than the smallest difference which we already found, we write the two values into an array and set the new smallest difference:

$result = [$arr[$keys[$key]], $arr[$keys[$innerKey]]];  $nearest = $diff;  

Code

  

Output

[5, 7]  

Answer by fusion3k for How can I determine two numbers that are more close than others in an array


It's not clear what happens in this situation:

$arr = array( 14, 20, 1, 5, 10, 7, 16 );  

In above case you have two couples with 2 as difference ( 7-5, 16-14 ). Following code returns all relative values.

We execute the standard two nested loops for comparing all elements (main loop excluding last element, nested loop starting from main index +1), then if the difference between current values is lower than previously retrieved difference, we replace it; otherwise, if the difference is equal to previous difference, we append a new couple:

$result = array( 'sum' => INF, 'values'=> array() );  for( $i=0; $i < count( $arr )-1; $i++ )  {      for( $j = $i+1; $j < count( $arr ); $j++ )      {          $dif = abs( $arr[$i] - $arr[$j] );          if( $dif < $result['sum'] )          {              $result = array( 'sum' => $dif, 'values'=> array( array( $arr[$i], $arr[$j] ) ) );          }          elseif( $dif == $result['sum'] )          {              $result['values'][] = array( $arr[$i], $arr[$j] );          }      }  }  

At this point, for above array sample, you have this result:

Array  (      [sum] => 2      [values] => Array          (              [0] => Array                  (                      [0] => 14                      [1] => 16                  )              [1] => Array                  (                      [0] => 5                      [1] => 7                  )          )  )  

If you are interested in all value, simply you can find them in $result['values']. Otherwise, if you want (i.e.) min values (5 and 7), you can usort-it:

usort( $result['values'], function( $a, $b ) { return min($a)-min($b); } );  

and use $result['values'][0]:

[0] => Array      (          [0] => 5          [1] => 7      )  

Answer by user5200704 for How can I determine two numbers that are more close than others in an array


try this

$arr = array (20, 1, 5, 10, 7, 16);   arsort($arr, SORT_NUMERIC);   $arr = array_values( $arr );    $min = 0;   foreach( $arr as $index => $number ){     if( isset($arr[$index+1]) ){       $diff = abs( $number - $arr[$index+1] );        if( $diff < $min || $min == 0 ){        $min = $diff;        $result = array( $number, $arr[$index+1] );       }     }        }   print_r( $result );  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.