抢红包算法,了解一下?

问题描述

emmmm,就是我们平常的抢红包金额分配问题。按照正常的思路,就是每次抢到的金额为随机区间(0,剩余金额)。但是问题也很明显,这样先抢的人就会有很大的优势,越到后面区间就越小,那么怎么保证每个人抢到的金额几率相等呢?

二倍均值法

即每次抢到的金额为区间:(0,平均值x2),例如:

假设10个人抢100元

第一个人抢到的金额随机区间为:(0,100/10*2) –> (0,20) 均值为10

假设第一个人抢到10元,那么第二个人抢到的随机区间为:(0,90/9*2) –> (0,20) 均值为10

这样也就保证了每个人抢到的金额均值一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static List<Integer> divider(int totalMoney, int totalPeople) {
List<Integer> amountList = new ArrayList<>();
int restMoney = totalMoney;
int restPeople = totalPeople;
Random random = new Random();
for (int i = 0; i < totalPeople - 1; i++) {
int amount = random.nextInt(restMoney / restPeople * 2) + 1;
restMoney -= amount;
restPeople--;
amountList.add(amount);
}
amountList.add(restMoney);
return amountList;
}

实现起来也并不是很难。

想法来源于@小灰

漫画:如何实现抢红包算法?

但是你仔细阅读文章的话,还是能注意到一个地方是有问题的。那就是“除了最后一次,任何一次抢到的金额都要小于人均金额的两倍”。

事实上并不是如此,因为如果第一个人抢到的值不是10,而是5,就会导致第二人抢到的均值大于10。

我们再看看知乎对这个问题的一个高票讨论,

微信红包的随机算法是怎样实现的?

实现也是差不多的,还有就是有人说到抢到的金额应该是服从正态分布的,大多数人抢到的值应该在均值附近。

关于架构方面可以看上面一篇文章。

看来一个小问题仔细思考还是有点东西的。


Android — 自定义View(六)之Path 贝塞尔曲线

前言

忍不住要吐槽一下了,自定义View系列已经写了五篇了,有点烦了。在看这节的标题,贝塞尔曲线,哇,以前曾经了解过一点,感觉好难啊。但是要实现很酷炫的效果,离不开贝塞尔曲线,怎么办?还能怎么办,学吧学吧,向现实低头!

其实,我只是想放一个这个图而已,2333333

好了,言归正传。按照惯例,先回顾上一节所学的内容,Path的基本操作。首先浮现在脑海中的是moveTo()、LineTo()、setLastPoint()这三个方法,也是比较容易理解的,重点是要分别moveTo()和setLastPoint()对之前绘制内容是否有影响的区别。紧接着,我们讲到了close()方法用来封闭路径,之后就是addXxx()一系列方法,值得一提的就是该方法中的一个枚举类型的参数,用来控制是顺时针(CW)还是逆时针(CCW)来绘制图形。

本节目录如下:

  1. 贝塞尔曲线原理简介
  2. 二阶贝塞尔曲线示例

more >>


Android — 自定义Behavior实现Toolbar颜色渐变

前言

上一篇中了解了协调布局CoordinatorLayout,可以协调子View之间的交互,那么它是怎么协调的呢?核心就是Behavior。同样的,上一节中,在处理AppbarLayout与NestedScrollView联动的时候,我们给NestedScrollView设置了一个Behavior,即:

1
app:layout_behavior="@string/appbar_scrolling_view_behavior"

这个Behavior是系统内置的。

这一节就自定义Behavior实现Toolbar颜色渐变,一图胜前言:

more >>


Android — CoordinatorLayout总结

CoordinatorLayout

CoordinatorLayout 即协调布局,它作为Layout的最外一层布局,可以协调子View做出特定响应动作的一个容器,这些响应动作是通过Behavior来指定的,比如用于协调AppbarLayout与ScrollView滑动的Behavior,如下:

1
2
3
4
5
6
7
8
9
10
11
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="18dp"
android:text="@string/large_text"/>
</android.support.v4.widget.NestedScrollView>

AppbarLayout

继承至LinearLayout,严重依赖于CoordinatorLayout ,必须用于CoordinatorLayout 的直接子View。它可以让你定制当某个可滑动的View滑动手势发生改变时,内部View响应一些动作。这些动作通过 app:layout_scrollFlags 来指定。

该值有以下几种:

  1. scroll 这个View会随着可滚动View一起滚动,就好像该子View属于ScrollView的一部分一样。
  2. enterAlways 当ScrollView向下滚动时,子View将直接向下滚动而不管ScrollView是否在滚动,要与 scroll 搭配使用,否则不能滑动。
  3. enterAlwaysCollapsed 当ScrollView向下滚动时,子View下滑至折叠的高度,当ScrollView到达滑动范围的结束值的时候,滑动View剩下的部分开始滑动,这个折叠的高度是通过View的minHeight(最小高度)指定的。必须要搭配 scroll|enterAlways一起使用。
  4. exitUntilCollapsed 当ScrollView滑出屏幕时,滑动View先响应滑动事件,滑动至折叠高度,也就是通过 minHeight设置的最小高度后,就固定不动了,再把滑动事件交给ScrollView继续滑动,需要搭配 srcoll 使用。
  5. snap 在滚动结束后,如果view只是部分可见,它将滑动到最近的边界。比如,如果View的底部只有49%可见,它将滚动离开屏幕,而如果底部有51%可见,它将滚动到完全显示。同样需要搭配 scroll 使用。

CollapsingToolbarLayout

是对Toolbar的包装并且实现了折叠app bar效果,使用时,要作为AppbarLayout的直接子View。有以下特性:

  1. Collapsing title(折叠标题)当布局全部可见的时候,title是最大的,当布局开始滑出屏幕,title将变得越来越小,可以通过setTitle来设置要显示的标题。

    但是当Toolbar和CollapsingToolbarLayout 同时设置了title时,不会显示Toolbar的title,如果要显示Toolbar的title,可以 collapsingToolbarLayout.setTitle(“”);

  2. Content scrim(内容纱布)当CollapsingToolbarLayout 滑动到一个确定的阈值时将显示会隐藏内容纱布,可以通过setContentScriom(Drawable)来设置内容纱布的图片。内容纱布也可以是颜色值 app:contentScrim=”@color/colorPrimary”。

  3. Status bar scrim(状态栏纱布)当CollapsingToolbarLayout 滑动到一个确定的阈值时,状态栏显示或隐藏纱布,可以通过 setStatusBarScrim(Drawable)来设置纱布图片。同内容纱布一样,状态栏纱布也可以是一个颜色值,在xml 中用statusBarScrim 属性指定。

  4. Parallax scrolling children (有视差的滚动子View)让CollapsingToolbarLayout 的子View可以有视差的滚动,需要在xml中通过app:layout_collapseMode=”parallax”指定。

  5. Pinned position children(固定子View的位置)子View可以固定在全局空间内,这对于实现了折叠并且允许通过滚动布局来固定Toolbar这种情况非常实用,通过 app:layout_collapseMode=”pin”来指定。

总结

CoordinatorLayout是协调子View的,通过Behavior指定子View动作。AppbarLayout就是一个竖直方向的LinearLayout,只不过它可以定制子View的滑动。CollapsingToolbarLayout 是对Toolbar的包装,它有五个特性。AppbarLayout要作为CoordinatorLayout的直接子View使用,而CollapsingToolbarLayout要作为AppbarLayout的直接子View使用。

Demo

没什么多说的,直接Fork:https://github.com/pinguo-zhouwei/MaterialDesignSamples


Android — Lottie初探及跳坑

前言

Lottie早就听过,但是由于播放动画的资源(Json文件)来源于AE,所以也就简单了解一下也没在继续下去了。今天我无意间看到一篇介绍Lottie的,随便看下吧,哇,赚!

不是自己没法用AE导出Json文件吗?不用怕,网上有人分享,Airbnb专门建立一个网站用来大家分享自己的Json,并且能预览动画:

https://www.lottiefiles.com/

既然有资源了,那就从官方文档开始尝试了:

http://airbnb.io/lottie/android/android.html#getting-started

文档也很详细就不多说了,只记录一下可能遇到的问题吧。

跳坑

依赖的时候遇到了我们用开源库经常碰到的v4包重复依赖的情况:DexException Multiple dex files define

通常的做法是在重复依赖的库中去掉v4包,即:

1
2
3
compile ('com.airbnb.android:lottie:2.5.1'){
exclude group: 'com.android.support'
}

但是这样并不能解决我的问题,网上搜了一下,可能需要分包,于是试了一下,还真行:

1
compile 'com.android.support:multidex:1.0.3'
1
2
3
4
defaultConfig {
/****/
multiDexEnabled true
}

添加分包支持就行了,总之这种问题就是哪几种解决办法,挨着试一遍就行了。

参考

https://blog.csdn.net/zgd826237710/article/details/79456202

https://www.jianshu.com/p/f769ea6db2c1

https://www.jianshu.com/p/0431a6c9c650

我们一直都向往,面朝大海,春暖花开。 但是几人能做到,心中有爱,四季不败?