现有视频若干,各视频有所属分类,数据项 格式如下
[
"id"=>1,
"cate_id"=>1
]
现有视频已按照指定规则排序完成
顺序排列中,连续的10个视频中,不能有属于相同分类的视频
//假设有100个分类,ID为 1-100 //$cates=[1,...,100];
//生成5000条视频数据
$video=[];
for ($i=1;$i<=5000;$i++){
$video[]=[
"id"=>$i,
"cate_id"=>mt_rand(1,100), //所属分类ID
"other"=>$i
];
}
function buildQueue($list=[],$step=10){
$data=[]; //接收生成的数据
$steps=[]; /**接收 因 前后10步长范围有相同分类导致无法插入的数据项,
存储格式为:
$steps = [
"cate_id"=>[
"wait"=>0-10 //需等待步长
"queue"=>[] //存储数据项
],
....
]
*/
//遍历$list插入$data数组 ,如果当前项前后10步长有相同分类元素,则追加进$steps数组
foreach ($list as $item){
if (isset($steps[$item["cate_id"]]["wait"])&&$steps[$item["cate_id"]]["wait"]>0){
//需等待步长耗尽
//dump("加入等待队列");
if (isset($steps[$item["cate_id"]]["queue"])){ //队列已存在
array_unshift($steps[$item["cate_id"]]["queue"],$item); //从头部追入数据,先进先出
}else{ //队列不存在
$steps[$item["cate_id"]]["queue"]=[$item]; //初始化队列
}
}else{ //无需等待步长
$steps[$item["cate_id"]]["wait"]=$step; //记录插入后在$steps中记录需等待步长10
$data[]=$item; //直接追加进$data数组
reduceSteps($steps,$data,$step); //操作$steps数组-为在等待的数据减去等待步长1
}
}
//debug start 打印$data中已保存的数据
//$i=1;
//foreach ($data as $datum){
// dump($i++.": ".$datum["id"].'-'.$datum["cate_id"]);
//}
//dump($steps); //$steps数组可能不为空,因为步长间距不足10
//debug end
//步长间距从10缩减到0,确保$steps清空,$list数据不丢失
for ($step-=1;$step>=0;$step--){
//dump("step:----------".$step);
//$num1=count($data)-1;
reduceSteps($steps,$data,$step);
//$num2=count($data)-1;
//for ($i=$num1;$i<=$num2;$i++){ //打印$data中本次追加的数据
// dump(($i+1).": ".$data[$i]["rate"].'-'.$data[$i]["id"].'-'.$data[$i]["cate_id"]);
//}
}
//dump($steps); 是否清空
return $data;
}
//$steps与$data使用引用类型,降低内存使用量,降低代码复杂度
function reduceSteps(&$steps,&$data,$step=10){
//为所有在等待的数据减去等待步长1
foreach ($steps as $key=>$datum){ //
if ($datum["wait"]>0){
$steps[$key]["wait"]--;
}
}
//处理在等待数据
foreach ($steps as $key=>$datum){
if ($datum["wait"] == 0){ //无需等待的数据
if (!empty($steps[$key]["queue"])){ //等待队列不为空
$data[]=array_pop($steps[$key]["queue"]); //弹栈,最先等待的数据最先弹出
$steps[$key]["wait"] = $step; //此cate_id分类继续等待步长
reduceSteps($steps,$data,$step); ////为所有在等待的数据减去等待步长1
}else{ //等待队列为空
unset($steps[$key]); //删除cate_id索引相关数据
}
//没有等待步长为0的数据,则跳出
}
}
}
dump(microtime(true));
$data=buildQueue($video);
dump(microtime(true));
foreach ($data as $datum) {
dump($datum["id"]."-".$datum["cate_id"]."-".$datum["other"]);
}
1637206150.3998
1637206150.4236
"1-77-1"
"2-85-2"
"3-25-3"
"4-94-4"
"5-22-5"
"6-61-6"
"7-66-7" // -- id:7 - 所属分类66
"8-56-8" // -- id:8 - 所属分类56
"10-51-10"
"11-27-11"
"12-8-12"
"13-100-13"
"14-65-14"
"16-52-16"
"17-11-17"
"18-91-18"
"9-66-9" // -- id:9 - 所属分类66 - 距离同分类 ID 7 步长10
"15-56-15" // -- id:15 - 所属分类56 - 距离同分类 ID 8 步长10
"19-55-19"
"20-43-20"
"21-46-21"
"22-50-22"
...
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。