亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

計算范圍之間的值

計算范圍之間的值

PHP
繁花不似錦 2022-07-09 10:52:47
我有兩個數組,一個是值,另一個是范圍:$ranges = array(10,15,30);$values = array(1,4,12,15,27,32);我想計算每個范圍之間的值的數量,例如:$output = array(    "<10" => 2, // number of values < 10    "10-15" => 1, // number of values >= 10 && < 15    "15-30" => 2, // number of values >= 15 && < 30    ">=30" => 1, // number of values > 30);顯然,ranges并且values是動態的,不能硬編碼if-conditions。到目前為止我所做的工作:$output = array();foreach ( $values as $val ) {    foreach ( $ranges as $k => $range ) {        if ( $k == 0 ) { // first range            $max = $range;            $label = '<' . $max;            if ( $val < $max ) {                $output[$label] += 1;            }        } else if ( $k == count($ranges) - 1 ) { // last range            $min = $ranges[$k-1];            $max = $range;            $label = $min . '-' . $max;            if ( $val >= $min && $val < $max ) {                $output[$label] += 1;            }            $min = $range;            $label = '>=' . $min;            if ( $val >= $min ) {                $output[$label] += 1;            }        } else {            $min = $ranges[$k-1];            $max = $range;            $label = $min . '-' . $max;            if ( $val >= $min && $val < $max ) {                $output[$label] += 1;            }        }    }}print_r($output);這似乎很昂貴,我真的不確定。有沒有更簡單的方法來實現我正在尋找的東西?
查看完整描述

4 回答

?
楊魅力

TA貢獻1811條經驗 獲得超6個贊

您可以通過在 $ranges 數組的開頭和結尾添加限制值來簡化邏輯,然后只需成對處理整個數組。


<?php


$ranges = [10,15,30];

$values = [1,4,12,15,27,32];

\array_push($ranges, null); // append null to array

\array_unshift($ranges, null); // prepend null to array


$output = [];

$count = \count($ranges);

for ($i = 0; $i < $count - 1; $i++) {

    $output[] = ['start' => $ranges[$i], 'end' => $ranges[$i+1], 'count' => 0];

}


foreach ($values as $value) {

    foreach ($output as $key => $range) {

        if (

             ($range['start'] === null || $range['start'] <= $value) &&

             ($range['end'] === null || $range['end'] > $value)

        ) {

            $output[$key]['count']++;

            break;

        }

    }

}


var_dump($output);


查看完整回答
反對 回復 2022-07-09
?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

$ranges首先使用數組中的鍵(使用)創建一個歸零數組array_fill_keys(),再加上一個用于“超過”最后一個條目的值。


循環遍歷每個值并根據范圍檢查它,如果找到它,它只會將相應的計數加 1 并停止查找。如果在完成循環后,該值大于最后一個范圍,則將 1 添加到“over”條目。


$ranges = array(10,15,30);

$values = array(1,4,12,15,27,32);


$rangeCount = array_fill_keys($ranges, 0);

$rangeCount[ "over" ] = 0;

foreach ( $values as $value )   {

    foreach ( $ranges as $range )   {

        if ( $value < $range )  {

            $rangeCount [ $range ]++;

            break;

        }

    }

    if ( $value >= $range )  {

        $rangeCount[ "over" ]++;

    }

}

print_r($rangeCount);

這使...


Array

(

    [10] => 2

    [15] => 1

    [30] => 2

    [over] => 1

)

只是為了添加一個只做一個循環的優化版本。但假設這些值是按升序排列的。每次它通過“當前”范圍時,它都會移動到下一個輸出計數器,最后一部分甚至不會循環超過最大值,它會從總計數中減去當前計數并中斷...


$currentRange = 0;

$numberValues = count($values);

$numberRanges = count($ranges);

$rangeCount = array_fill(0, $numberRanges, 0);

$rangeCount[ "over" ] = 0;

foreach ( $values as $count => $value )   {

    if ( $value >= $ranges[$currentRange] )   {

        $currentRange++;

        if ( $currentRange >= $numberRanges )    {

            $rangeCount[ "over" ] = $numberValues - $count;

            break;

        }

    }

    $rangeCount[$currentRange]++;

}

print_r($rangeCount);


查看完整回答
反對 回復 2022-07-09
?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

以下解決方案首先按升序/非降序對范圍進行排序。

然后,我們創建一個range_map它是所有可能范圍的集合$ranges。

然后,我們遍歷所有值$values并進行二進制搜索以$ranges獲得特定值所屬的確切范圍索引。在下面的代碼中,精確索引存儲在$low.


然后,我們只需通過取范圍鍵$range_map并將其計數器加 1 來收集計數。


這比嵌套循環更快,因為嵌套循環的時間復雜度O(m*n)是m大小$ranges和n大小$values,而當前解決方案的時間復雜度O(m logm) + O(n logm)是m大小$ranges和n大小$values。


片段:


<?php


$ranges = array(10,15,30);

$values = array(1,4,12,15,27,32);


sort($ranges);


$range_map = [];

$ptr = 0;


foreach($ranges as $index => $value){

    if($index === 0) $range_map[$ptr++] =  "<" . $value;

    if($index > 0) $range_map[$ptr++] = $ranges[$index - 1] . "-" . $value;

    if($index === count($ranges) - 1) $range_map[$ptr++] = ">=" . $value;

}


$result = [];


foreach($values as $value){

    $low = 0; $high = count($ranges) - 1;

    while($low <= $high){

        $mid = $low + intval(($high - $low) / 2);

        if($value === $ranges[ $mid ]){

            $low = $mid + 1;

            break;

        }else if($value < $ranges[ $mid ]){

            $high = $mid - 1; 

        }else{

            $low = $mid + 1;

        }

    }


    if(!isset($result[$range_map[$low]])) $result[$range_map[$low]] = 0; // get the range key from range_map

    $result[$range_map[$low]]++; // increment the value for that range

}


print_r($result);

演示: https ://3v4l.org/JcYBv


查看完整回答
反對 回復 2022-07-09
?
叮當貓咪

TA貢獻1776條經驗 獲得超12個贊

假設您有預先排序的范圍和值。


<?php

$ranges = array(10,15,30);

$values = array(1,4,12,15,27,32);


$lower = null;

$i = 0;

$upper = $ranges[$i];

foreach($values as $item) {

    if(!is_null($upper) && $item >= $upper) {

        $lower = $upper;

        $upper = $ranges[++$i] ?? null;

    }

    $result["$lower<$upper"][] = $item;

}


var_export(array_map('count', $result));

輸出:


array (

    '<10' => 2,

    '10<15' => 1,

    '15<30' => 2,

    '30<' => 1,

  )


查看完整回答
反對 回復 2022-07-09
  • 4 回答
  • 0 關注
  • 155 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號