数据流中的中位数

题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
解题思路:
将输入的数组先进行排序,然后寻找中位数。
下面代码使用的是直接选择排序的方法。

**
 * Created by Administrator on 2017/4/14.
 */
public class Solution29 {
    public static Object Median(Integer[] array){
        if ((array.length)%2 != 0){
            return array[(array.length-1)/2];
        }else if (array.length%2 == 0){
            int c = array.length/2;
            return ((array[c-1]) + (array[c]))/2;
        }
        return 0;
    }
    public static void selectSort(Integer[] keys)              //直接选择排序(升序)
    {
        System.out.println("直接选择排序(升序)");
        for (int i=0; i<keys.length-1; i++)                //n-1趟排序
        {
            int min=i;
            for (int j=i+1; j<keys.length; j++)            //每趟在从keys[i]开始的子序列中寻找最小元素
                if (keys[j]<keys[min])                     //(升序)
//                if (keys[j]>keys[min])                     //(降序)
                    min = j;                              //min记住本趟最小元素下标
            System.out.print("第"+(i+1)+"趟,下标"+i+"~"+(keys.length-1)+",min="+min+",");
            if (min!=i)                                    //将本趟最小元素交换到前边
                swap(keys, i, min);
            print(keys);
        }
        System.out.println(Median(keys));
    }
    private static void swap(Integer[] keys, int i, int j)     //交换keys[i]与keys[j]元素,i、j范围由调用者控制
    {
        int temp = keys[j];
        keys[j] = keys[i];
        keys[i] = temp;
    }
    public static void print(Object[] value){ //打印排序后的数组
        for (Object obj : value){
            System.out.print(obj == null ? "null" : " "+obj.toString());
        }
        System.out.println();
    }
    public static void main(String args[]){
        Integer[] array = {5,2,4,6};
        selectSort(array);
    }
}
//输出:
//直接选择排序(升序)
//        第1趟,下标0~3,min=1, 2 5 4 6
//        第2趟,下标1~3,min=2, 2 4 5 6
//        第3趟,下标2~3,min=2, 2 4 5 6
//        默认取整了:
//        4
//
//        Process finished with exit code 0
计算数据流中位数可以通过Flink的ProcessFunction来实现。 具体实现步骤如下: 1. 将数据流按照大小排序 2. 计算数据流的长度,如果是奇数,则中位数为第 (length+1)/2 个元素;如果是偶数,则中位数为第length/2个元素和第(length/2+1)个元素的平均值。 3. 在ProcessFunction的实现,可以使用状态变量来保存数据流的有序列表,并计算中位数。 以下是一个简单的示例代码: ```java public class MedianFunction extends ProcessFunction<Integer, Double> { private ListState<Integer> values; @Override public void open(Configuration parameters) throws Exception { super.open(parameters); values = getRuntimeContext().getListState(new ListStateDescriptor<Integer>("values", Integer.class)); } @Override public void processElement(Integer value, Context ctx, Collector<Double> out) throws Exception { values.add(value); List<Integer> sortedValues = new ArrayList<>(); for (Integer v : values.get()) { sortedValues.add(v); } Collections.sort(sortedValues); int length = sortedValues.size(); if (length % 2 == 0) { double median = (sortedValues.get(length/2) + sortedValues.get(length/2 - 1)) / 2.0; out.collect(median); } else { double median = sortedValues.get(length/2); out.collect(median); } } } ``` 在上述代码,我们使用了ListState来保存数据流的元素,并在每次处理新元素时重新排序并计算中位数。注意,这只是一个简单的示例,实际应用需要考虑更多的问题,比如数据倾斜、数据丢失等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马超的博客

谢谢大佬的赞赏 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值