一个随机播放的算法II

一个随机播放的算法

Idea:💡

音乐时光🎵
骑着车,戴着耳机,播放列表里有几首歌。
突然,很想听《且听风吟》,但是不想掏出手机,于是一路双击耳机播放键切歌。
emmm,下面是切过的歌:

第几次 随机到的音乐 停留的时间
1 Love Story 2s
2 东风破 3s
3 Refrain 1s
4 东风破 2s
5 Valder Fields 2s
6 Love Story 1s
7 My Soul 3s
8 白金ディスコ 1s
9 Refrain 3s
... ... ...
16 且听风吟 3min

What?一共才几首歌,而我切了十多次才随机到自己想要的!
有些歌明明已经被切掉了,为什么马上又随机到?不够聪明诶。

那么,在监听到用户正在切歌时,可不可以直接跳过刚刚已经切过的歌?
当然是可行的。于是在RandomPicker基础上实现了CutMode。进入切歌模式后,切过的歌将不会再次出现,除非一轮已经切完。

Demo

进入切歌模式的RandomPicker

如何使用

快速开始:

// 指定列表有n首歌,初始比重为1.
mRandomPicker = new RandomPicker(n, 1); 
// 进入切歌模式。
mRandomPicker.enterCutMode();
// 随机获取下一首
int nextPos = mRandomPicker.next();
...
// 退出切歌模式
mRandomPicker.exitCutMode();

更多方法:

// 更默认的比重计算器
mRandomPicker.setCalculator(new Calculator() {
@Override
public int calculateNextWeight(int currentWeight, int originWeight) {
    return (currentWeight + 1) * originWeight;
    }
 });
// 改变某个item的初始比重
mRandomPicker.changeOriginWeight(0, 3);
// 指定下次随机到的数
mRandomPicker.setNextPick(3);
//添加一个item至尾部,并为其赋值初始比重
mRandomPicker.add(2);

源码

GitHub: XunMengWinter/RandomPicker

下面贴出关键代码:

    /*执行随机算法*/
    private int randomPick() {
        // 若列表长度小于2,则下一次位置必为0.
        if (mCurrentWeightList.size() < 2) {
            return 0;
        }

        int nextPos = 0;
        // 算出下一次选中的位置
        if (mNextPickPosition != null) {
            nextPos = mNextPickPosition;
            mNextPickPosition = null;
        } else {
            int allWeight = 0;
            for (int i = 0; i < mCurrentWeightList.size(); i++) {
                allWeight += mCurrentWeightList.get(i);
            }

            if (allWeight <= 0) {
                //TODO avoid this situation.
                allWeight = Integer.MAX_VALUE;
                //Log.e(TAG, "...");
            }

            int nextPosInWeight = mRandom.nextInt(allWeight);
            int currentWeight = 0;
            for (int i = 0; i < mCurrentWeightList.size(); i++) {
                currentWeight += mCurrentWeightList.get(i);
                if (currentWeight > nextPosInWeight) {
                    nextPos = i;
                    break;
                }
            }
        }

        // 预先算好下一次的比重
        for (int i = 0; i < mCurrentWeightList.size(); i++) {
            if (isCutMode()) {
                if (mCutOutSet.contains(i)) {
                    continue;
                }
            }
            int weight = calculateWeight(mCurrentWeightList.get(i), mOriginWeightList.get(i));
            mCurrentWeightList.set(i, weight);
        }
        if (isRepeatable)
            mCurrentWeightList.set(nextPos, calculateWeight(0, mOriginWeightList.get(nextPos)));
        else
            mCurrentWeightList.set(nextPos, 0);

        if (isCutMode()) {
            mCurrentWeightList.set(nextPos, 0);
            mCutOutSet.add(nextPos);
            if (mCutOutSet.size() >= getSize())
                mCutOutSet.clear();
        }
        return nextPos;
    }

p.s. 如果你有更好的建议,请留言或者在GitHub fork并提交pull请求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 想法: 伪随机。你的音乐列表里有一些歌,每首歌的初始随机因数为1。每次你点击下一首时,每首歌的随机因数都会加1,然...
    DreamWinter阅读 4,559评论 7 51
  • 写在前面 1、基于create-react-app脚手架创建,仿网易云音乐web端的一个音乐播放器2、现在处于1....
    子白青墨阅读 6,933评论 0 7
  • (一) 你听歌吗? 一个人走路的时候,一个人运动的时候,一个人做些不费精力的琐碎事情的时候,你会不会,寻一对耳机,...
    雾音舞阅读 346评论 0 1
  • 7月24日 小雨转晴 星期三 记得上次开亲子日记家长会的时候,马校长讲了一句话,教育孩子首先...
    王会萍阅读 95评论 0 0
  • 晓云和海洋是大学同班同学,现在的话来讲就是好闺蜜,蓝颜知己。晓云和海洋都是单身,晓云有一次上课的时候无意提到住...
    禾玉阅读 1,112评论 2 1

友情链接更多精彩内容