按照分数和题目数量限制从题库抽题

// 定义一个全局变量,存储分数数组集合
private $ans = [];

// 完成主要业务
public function test(){
  // 取出分数
$data=DB::table('test')->whereNotNull('score')->get()->toArray();
$data = array_column($data,'score');

// 获取考试设置
$total_grade = 100;
$exam_number = 35;
// 排列分数组合

sort($data);
// 递归+回溯获取所有分数满足指定分数的数组集合
$this->backtrack($data,$total_grade,0,[]);
$list = collect($this->ans);
}

// 采用collcet集合方法random(),从集合中返回一个随机项
$score_combination = collect($combination)->random();

// 根据随机的这个数组去题库中随机抽题;ps:这个抽出来的题题目有重复的
$random_data  = ExamQuestionBank::whereIn('score',$score_combination)->inRandomOrder()->get()->toArray();
$return_data = [];
$del = [];
// 统计这个组合有多少个
$combination_count = count($score_combination);

// 对题库中抽出来的题进行去重,并且抽取相应数量
foreach ($random_data as $key=>$val){
	foreach ($score_combination as $k => $v){
		// 如果题库中的分数等于分数组合中的分数,并且这个题库id还不在del数组中
		if ($val['score'] == $v && !in_array($key,$del)){
		// 返回的数据添加上这个value
		$return_data[] = $val;
		// 销毁分数数组中的这个分数
		unset($score_combination[$k]);
		// 将已经返回的id添加到del数组中,确保下次筛选不会有重复的数据
		$del[] = $key;
			}
		}
	// 如果返回的数据数量等于分数组合的数量,那么就跳出循环,把抽题后的数据返回回去
	if (count($return_data) == $combination_count){
	break;
	}
	return $return_data;
}


// 递归加回溯找出所有分数组合
public function backtrack($candidates,$target,$start,$list){
        if($target < 0){
            $this->create([],'总分小于0!',201);
        }else if($target == 0){
            $this->ans[] = $list;
        }else{
            for($i=$start;$i<count($candidates) && ($target-$candidates[$i])>=0;$i++){
                if($i>$start && $candidates[$i] == $candidates[$i-1]){
                    continue;
                }
                array_push($list,$candidates[$i]);
                $this->backtrack($candidates,$target-$candidates[$i],$i+1,$list);
                array_pop($list);
            }
        }
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值