队列:推荐结果打散

队列:推荐结果打散

什么是推荐结果打散?

以小视频推荐的那种功能为例,为了圆子,都是包含广告和小视频的。

那肯定不能全部推荐广告,必须是几个视频中夹杂着广告,比如你刷了20个,就给你弹一个广告出来,是有一个固定的顺序的。

推荐结果打散就是确保每个广告和广告之间,确保包含几个视频,这种效果。

代码

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 以小视频推荐的那种功能为例,为了圆子,都是包含广告和小视频的。
 * <p>
 * 那肯定不能全部推荐广告(ad),必须是几个视频(video)中夹杂着广告,比如你刷了20个,就给你弹一个广告出来,是有一个固定的顺序的。
 * <p>
 * 推荐结果打散就是确保每个广告和广告之间,确保包含几个视频,这种效果。
 */
public class KanDianTest {

    /**
     * 获得被推荐的结果
     *
     * @param adAndVideo:  ad和video的集合
     * @param maxInterval: ad和video的间隙数量,自首个ad出现后,每maxInterval个video后,后面必然是一个ad
     * @return
     */
    public List<String> getRecommendenResult(List<String> adAndVideo, int maxInterval) {
        List<String> result = new ArrayList<>();
        if (adAndVideo == null || adAndVideo.size() == 0) {
            return result;
        }
        /*声明两个队列,一个是存储video,一个存储ad*/
        Queue<String> videoQueue = new LinkedList<>();
        Queue<String> adQueue = new LinkedList<>();
        boolean firstAd = false;//判断开头是否是ad
        int index = 0;
        int adAndVideoSize = adAndVideo.size();
        while (!firstAd && index < adAndVideoSize) {//判断有没有firstAd,第一次出现ad则跳出此循环,否则一直向result添加video
            if (isVideo(adAndVideo.get(index))) {//adAndVideo index=0为ad,则不执行result.add
                result.add(index, adAndVideo.get(index));
                index++;
            } else {
                firstAd = true;
            }
        }

        /*向各自的队列添加元素*/
        while (index < adAndVideoSize) {
            if (isVideo(adAndVideo.get(index))) {
                videoQueue.add(adAndVideo.get(index));
            } else {
                adQueue.add(adAndVideo.get(index));
            }
            index++;
        }

        /*两个队列都不为空,开始向结果队列添加元素*/
        int currentSize = result.size();//用来验证result中video的数量,代表video和ad的间隙,首次为第一次出现ad的下标
        while (!videoQueue.isEmpty() && !adQueue.isEmpty()) {
            if (currentSize >= maxInterval) {//数量>允许存在的ad的数量,加ad
                result.add(adQueue.poll());
                currentSize = 0;//添加ad后,间隙归零,重新计算
            } else {//不大于,加video,adAndVideo index=0为ad,就是走的这个
                result.add(videoQueue.poll());
                currentSize++;
            }
        }

        /*ad放完之后,video仍存在,则加完video*/
        while (!videoQueue.isEmpty()) {
            result.add(videoQueue.poll());
        }

        /*不考虑adQueue为空的情况*/

        /*videoQueue为空,adQueue还有的情况*/
        if (currentSize >= maxInterval && !adQueue.isEmpty()) {//当前间隙大于最大间隙,则允许再插入一个ad
            result.add(adQueue.poll());
        }
        return result;
    }

    /**
     * 判断是否是video
     * 我这只简单判断,根据名字关键字判断
     *
     * @param clip
     * @return
     */
    private boolean isVideo(String clip) {
        if (clip.indexOf("video") != -1) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        list1.add("ad0");
        list1.add("ad1");
        list1.add("ad2");
        list1.add("video0");
        list1.add("video1");
        list1.add("video2");
        list1.add("video3");
        list1.add("video4");

        list2.add("video0");
        list2.add("video1");
        list2.add("video2");
        list2.add("video4");
        list2.add("video5");
        list2.add("video6");
        list2.add("ad0");
        list2.add("ad1");
        list2.add("video7");

        List<String> result1 = new KanDianTest().getRecommendenResult(list1, 3);
        List<String> result2 = new KanDianTest().getRecommendenResult(list2, 3);
        System.out.println(result1);
        System.out.println(result2);
        /**
         * [video0, video1, video2, ad0, video3, video4]
         * [video0, video1, video2, video4, video5, video6, ad0, video7]
         */
    }
}

图解

队列:推荐结果打散

上一篇:2021-10-29


下一篇:5-8.定义媒介资源