You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Java代码实现数组的移动中位数并得到预期结果?

问题排查与解决方案

嘿,咱先揪出核心问题:你main方法里的Scanner用法完全搞错了,导致传给getMedians的数组根本不是你想要的{6, 12, 4, 5, 3, 8, 7},自然算不出正确结果。

具体来说,String.valueOf(adio)不会把数组元素转成逗号分隔的字符串,它返回的是数组的默认toString结果(比如[I@1b6d3586这种格式)。用Scanner读这个字符串,要么直接抛输入不匹配异常,要么读出来的数值完全不对,等于你给计算逻辑喂了个错误的数组,结果肯定跑偏。

修复步骤

直接砍掉错误的Scanner处理逻辑,把目标数组直接传给getMedians就行。而且你的中位数计算逻辑本身是对的,只要传对数组就能得到正确的运行中位数。

修改后的完整代码

import java.util.*;

public class Movmedian {
    /**
     * 向堆中添加元素
     */
    public static void addNumber(int num, PriorityQueue<Integer> lowers, PriorityQueue<Integer> highers) {
        if (lowers.size() == 0 || num < lowers.peek()) {
            lowers.add(num);
        } else {
            highers.add(num);
        }
    }

    /**
     * 平衡两个堆的大小
     */
    public static void rebalance(PriorityQueue<Integer> lowers, PriorityQueue<Integer> highers) {
        PriorityQueue<Integer> biggerHeap = lowers.size() > highers.size() ? lowers : highers;
        PriorityQueue<Integer> smallerHeap = lowers.size() > highers.size() ? highers : lowers;

        if (biggerHeap.size() - smallerHeap.size() >= 2) {
            smallerHeap.add(biggerHeap.poll());
        }
    }

    /**
     * 获取当前的中位数
     */
    public static double getMedian(PriorityQueue<Integer> lowers, PriorityQueue<Integer> highers) {
        PriorityQueue<Integer> biggerHeap = lowers.size() > highers.size() ? lowers : highers;
        PriorityQueue<Integer> smallerHeap = lowers.size() > highers.size() ? highers : lowers;

        if (biggerHeap.size() == smallerHeap.size()) {
            return ((double) biggerHeap.peek() + smallerHeap.peek()) / 2;
        } else {
            return biggerHeap.peek();
        }
    }

    /**
     * 计算数组的运行中位数
     * @param array 输入数组
     */
    public static double[] getMedians(int[] array) {
        // 大顶堆,存较小的一半元素(用Comparator.reverseOrder()替代匿名内部类,更简洁)
        PriorityQueue<Integer> lowHeap = new PriorityQueue<>(Comparator.reverseOrder());
        // 小顶堆,存较大的一半元素
        PriorityQueue<Integer> highHeap = new PriorityQueue<>();
        double[] medians = new double[array.length];

        for (int i = 0; i < array.length; i++) {
            int number = array[i];
            addNumber(number, lowHeap, highHeap);
            rebalance(lowHeap, highHeap);
            medians[i] = getMedian(lowHeap, highHeap);
            System.out.println(medians[i]); // 打印每一步的运行中位数
        }
        return medians;
    }

    /**
     * 主方法
     */
    public static void main(String[] args) {
        // 直接传入目标数组,去掉错误的Scanner处理
        int[] adio = {6, 12, 4, 5, 3, 8, 7};
        getMedians(adio);
    }
}

运行结果验证

修改后运行代码,输出的运行中位数是:

6.0
9.0
6.0
5.5
5.0
5.5
6.0

这和你提到的@xtratic修改后的结果一致,说明你的计算逻辑没问题。如果你预期的是12.0 8.0 5.0 4.5 5.0 6.0,那大概率是对移动中位数的定义理解不同——当前代码实现的是逐个添加元素的运行中位数(每加入一个元素后,计算当前所有元素的中位数),而不是固定窗口大小的滑动中位数(比如窗口大小为3的滑动窗口)。如果需要滑动窗口中位数,那得调整逻辑,但当前代码的运行中位数实现是正确的。

补充:正确的控制台输入方式

如果你确实需要从控制台读取数组,正确的Scanner用法应该是这样:

public static void main(String[] args) {
    Scanner ini = new Scanner(System.in);
    System.out.print("请输入数组长度:");
    int n = ini.nextInt();
    int[] a = new int[n];
    System.out.print("请输入数组元素(空格分隔):");
    for(int i=0; i < n; i++){
        a[i] = ini.nextInt();
    }
    getMedians(a);
    ini.close();
}

这样就能正确读取用户输入的数组并计算中位数。

内容的提问来源于stack exchange,提问作者Jonatino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:08:35