題意是這樣的:求解一個數組中元素a和b,其和sum=a+b,sum最接近num的數兩個。array是一個整型數組。
其求解方式如下:
//求解數組中元素a和b,其和sum=a+b,sum最接近num的數兩個。
//求解思想是:對數組進行順序排序,然後對數組中的每個數遍歷每個數能求得一個最優值,然後對每對值大小sum與給出的這個數num做比較,找出絕對值相差最小的那個數。
//以下程序是對以上的一個簡單變化,其比較的是兩個值sum-num的絕對值大小,找到絕對值最小的值。
//這個過程就是流水式的,在一次流水式的比較和判定過程就能確定下來,將對應的值存儲在變量中,這裏是c_1和c_2。
//這裏還有帶說明的是,在固定一個值查找另外一個值時,我使用的是$tmp=$num - $array[$i]查出與該數最接近的數,並返回其下標,獲取對應的值最終就可以得到最小的最優值。
//只要該最優值最小,就可以確定該組數值。
$array = [5,67,56,32,16,19];
//$c_1,$c_2是存放找到的兩個數值。
$c_1 = 0;
$c_2 = 0;
//最優值,在這裏其
$opt = 0;
//輸入的數
$num = 33;
//開始:
//分兩步
//1.先排序
//2.判定
//3.查找
sort($array);
//依次遍歷數組中的數其每個值的最優值
$length = count($array);
//數組元素個數大於2個
if($length < 2) exit("error array length");
//判斷端數值
if($num <= ($array[0] + $array[0])){
$c_1 = $array[0];
$c_2 = $array[1];
}
else if($num >= ($array[$length - 1]+$array[$length-1]))
{
$c_1 = $array[$length-1];
$c_2 = $array[$length-2];
}
else {
//初始化最優值
$opt = $array[0] + $array[$length - 1] - $num;
if($opt < 0) $opt = -$opt;
for($i=0;$i<$length;$i++)
{
//獲取相對的num跟接近的數。
$tmp = $num - $array[$i];
if($tmp <= 0) $tmp = -$tmp;
$node = search($i,$tmp, $array);
//當前查找的最優值的記錄
$opt2 = $node + $array[$i] - $num;
//取其絕對值,也可用abs()取絕對值$opt2 = abs($opt2);
if( $opt2 < 0) $opt2 = -$opt2;
//判定做比較,找出最小的絕對值,並將其賦值給$c_1和$c_2
if($opt2 < $opt) {
$opt = $opt2;
$c_1 = $array[$i];
$c_2 = $node;
}
}
}
print_r($array);
echo "find ".$num." in array,".$c_1." and ".$c_2." sub more close";
//給定一個值求出和它最接近的數
//採用折半查找,查找該元素數值
function search($key,$num, $array)
{
//lft,$right左右折半下標指針
$left = 0;
unset($array[$key]);
//$tmpKeys = array_keys($array);
$array = array_merge($array,[]);
$right = count($array) - 1;
//中間指針
$half = floor(($left + $right) / 2);
//current爲當前指針
$current = $left;
//跳出循環的標誌符號,其只要在最後一輪,能判定已經是相鄰的兩個數,就能結束循環了。
$next = 0;
while($left <= $right)
{
$half = floor(($left + $right) / 2);
$next = $right - $left;
if($num == $array[$half])
{
$current = $half;
break;
}
elseif ($num > $array[$half]) {
$left = $half;
}
以上是找一個數組中任意兩個數的和最接近,但這也只是記錄單對數字,其實要優化也可以將其他多對相關的數字記錄下來。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
爲了search()返回以前下標,並非數字結果,我們可以這樣做。
//求解數組中元素a和b,其和sum=a+b,sum最接近num的數兩個。
//求解思想是:對數組進行順序排序,然後對數組中的每個數遍歷每個數能求得一個最優值,然後對每對值大小sum與給出的這個數num做比較,找出絕對值相差最小的那個數。
//以下程序是對以上的一個簡單變化,其比較的是兩個值sum-num的絕對值大小,找到絕對值最小的值。
//這個過程就是流水式的,在一次流水式的比較和判定過程就能確定下來,將對應的值存儲在變量中,這裏是c_1和c_2。
//這裏還有帶說明的是,在固定一個值查找另外一個值時,我使用的是$tmp=$num - $array[$i]查出與該數最接近的數,並返回其下標,獲取對應的值最終就可以得到最小的最優值。
//只要該最優值最小,就可以確定該組數值。
$array = [5,12,34];
//$c_1,$c_2是存放找到的兩個數值。
$c_1 = 0;
$c_2 = 0;
//最優值,在這裏其
$opt = 0;
//輸入的數
$num = 33;
//開始:
//分兩步
//1.先排序
//2.判定
//3.查找
sort($array);
//依次遍歷數組中的數其每個值的最優值
$length = count($array);
//數組元素個數大於2個
if($length < 2) exit("error array length");
//判斷端數值
if($num <= ($array[0] + $array[0])){
$c_1 = $array[0];
$c_2 = $array[1];
}
else if($num >= ($array[$length - 1]+$array[$length-1]))
{
$c_1 = $array[$length-1];
$c_2 = $array[$length-2];
}
else {
//初始化最優值
$opt = $array[0] + $array[$length - 1] - $num;
if($opt < 0) $opt = -$opt;
for($i=0;$i<$length;$i++)
{
//獲取相對的num跟接近的數。
$tmp = $num - $array[$i];
if($tmp <= 0) $tmp = -$tmp;
$node = search($i,$tmp, $array);
echo $node."\n";
//當前查找的最優值的記錄
$opt2 = $array[$node] + $array[$i] - $num;
//取其絕對值,也可用abs()取絕對值$opt2 = abs($opt2);
if( $opt2 < 0) $opt2 = -$opt2;
//判定做比較,找出最小的絕對值,並將其賦值給$c_1和$c_2
if($opt2 <= $opt) {
$opt = $opt2;
$c_1 = $array[$i];
$c_2 = $array[$node];
}
}
}
print_r($array);
echo "find ".$num." in array,".$c_1." and ".$c_2." sub more close";
//給定一個值求出和它最接近的數
//採用折半查找,查找該元素數值
function search($key,$num, $array)
{
//lft,$right左右折半下標指針
$left = 0;
unset($array[$key]);
$tmpArray = [];
$j = 0;
foreach($array as $k => $v){
$tmpArray[$j]['key'] = $k;
$tmpArray[$j]['val'] = $v;
$j++;
}
$right = count($tmpArray) - 1;
//中間指針
$half = floor(($left + $right) / 2);
//current爲當前指針
$current = $left;
//跳出循環的標誌符號,其只要在最後一輪,能判定已經是相鄰的兩個數,就能結束循環了。
$next = 0;
while($left <= $right)
{
$half = floor(($left + $right) / 2);
$next = $right - $left;
if($num == $tmpArray[$half]['val'])
{
$current = $half;
break;
}
elseif ($num > $tmpArray[$half]['val']) {
$left = $half;
}
elseif($num < $tmpArray[$half]['val']) {
$right = $half;
}
if(($num - $tmpArray[$left]['val']) <= ($tmpArray[$right]['val'] - $num)){
$current = $left;
}
else{
$current = $right;
}
if($next <= 1) break;
}
return $tmpArray[$current]['key'];
}