首页 > 解决方案 > 从数组中获取移动中位数

问题描述

我试图弄清楚如何从数组中获取移动中位数。我在下面的代码中遇到错误,我将感谢您对解决方案的帮助。

 import java.util.*;
    public class Movmedian {
        /**
         * The add number method
         */
        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);
            }
        }
        /**
         * The rebalance method
         */
        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());
            }
        }
        /**
         * The get median method
         */
        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();
            }
        }
        /**
         * The get medians method
         * @param array
         */
        public static double[] getMedians(int[] array) {
            PriorityQueue<Integer> lowHeap = new PriorityQueue<Integer>(new Comparator<Integer>(){
                public int compare(Integer a, Integer b) {
                    return -1 * a.compareTo(b);
                }
            });
            PriorityQueue<Integer> highHeap = new PriorityQueue<Integer>();
            double[] medians = new double[array.length];
            /**
             * The loop
             */
            for(int i=0; i < array.length; i++){
                int number = (int) array[i];
                addNumber(number,lowHeap,highHeap);
                rebalance(lowHeap,highHeap);
                medians[i] = getMedian(lowHeap,highHeap);
                System.out.println(medians[i]);//this is the running median
            }
            return medians;
        }
        /**
         * The main
         */
        public static void main(String[] args) {
            int[] adio = {6, 12, 4, 5, 3, 8, 7};
            Scanner ini = new Scanner(String.valueOf(adio));
            int n = ini.nextInt();
            int[] a = new int[n];
            for(int i=0; i < a.length; i++){
                a[i] = ini.nextInt();
            }
            getMedians(a);

        }
    }

我希望得到输出 12.0 8.0 5.0 4.5 5.0 6.0 但在代码中出现错误。如何修改它以使用数组获得预期结果。当我使用@xtratic 所做的更正时,我得到了答案 6.0 9.0 6.0 5.5 5.0 5.5 6.0

When  I use scanner method below I obtain the correct answer which is 12.0 8.0 5.0 4.5 5.0 6.0
Scanner in = new Scanner(System.in);
      int n = in.nextInt();
      int[] a = new int[n];
      for(int i=0; i < a.length; i++){
       a[i] = in.nextInt();
        }

            getMedians(a);
        }

When I modify code below to use array
public static void main(String[] args) {
           double [] adio = {6.0, 12.0, 4.0, 5.0, 3.0, 8.0, 7.0 };
           double[] a = adio.clone();
            getMedians(a);
        }
I get the 6.0 9.0 6.0 5.5 5.0 5.5 6.0 
Please how do I modify this code using array to get the correct answer 
12.0 8.0 5.0 4.5 5.0 6.0 

谢谢

标签: java

解决方案


我试图弄清楚如何从数组中获取移动中位数。我在下面的代码中遇到错误,我将感谢您对解决方案的帮助。Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at kmeans.Movmedian.main(Movmedian.java:69)这就是错误。

改用它,它将克隆原始列表,就像您打算做的那样。

public static void main(String[] args) {
    int[] adio = {6, 12, 4, 5, 3, 8, 7 };
    int[] a = adio.clone();
    getMedians(a);
}

问题是:

    public static void main(String[] args) {
        int[] adio = {6, 12, 4, 5, 3, 8, 7};
        // `String.valueOf(adio)` returns something like "[I@7a9273a8"
        Scanner ini = new Scanner(String.valueOf(adio));
        // `nextInt()` fails when scanning from "[I@7a9273a8"
        int n = ini.nextInt();
        int[] a = new int[n];
        for(int i=0; i < a.length; i++){
            a[i] = ini.nextInt();
        }
        getMedians(a);
    }

使用第Scanner一个 int 时只用于设置数组的长度,不用作数组中的值:

int n = in.nextInt(); // first int
int[] a = new int[n];
for(int i=0; i < a.length; i++){ // second and more ints
   a[i] = in.nextInt();
}

但是当您传入数组时,您将第一个6作为值包含在数组中:

double [] adio = {6.0, 12.0, 4.0, 5.0, 3.0, 8.0, 7.0 };
double[] a = adio.clone();
getMedians(a);

相反,在传入数组时,您应该放弃第一个6,因为它只是告诉数组的长度。改为这样做:

//              no 6
double [] adio = {12.0, 4.0, 5.0, 3.0, 8.0, 7.0 };
double[] a = adio.clone();
getMedians(a);

推荐阅读