如何计算数组的中位数?

Wil*_*ill 38 java arrays

我正在尝试计算由文本字段接收的输入填充的数组的总数,平均值和中位数.我已经设法计算出总数和均值,我只是无法得到中位数.我认为在我能做到这一点之前需要对数组进行排序,但我不知道如何做到这一点.这是问题,还是有另一个我没找到的?这是我的代码:

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;

public class whileloopq extends Applet implements ActionListener
{
    Label label;
    TextField input;
    int num;
    int index;
    int[] numArray = new int[20];
    int sum;
    int total;
    double avg;
    int median;



    public void init ()
    {
        label = new Label("Enter numbers");
        input = new TextField(5);
        add(label);
        add(input);
        input.addActionListener(this);
        index = 0;
    }

    public void actionPerformed (ActionEvent ev)
    {
        int num = Integer.parseInt(input.getText());
        numArray[index] = num;
        index++;
        if (index == 20)
        input.setEnabled(false);
            input.setText("");
        sum = 0;
        for (int i = 0; i < numArray.length; i++)
        {
            sum += numArray[i];
        }
        total = sum;
        avg = total / index;

        median = numArray[numArray.length/2];



        repaint();

    }



    public void paint (Graphics graf)
    {



        graf.drawString("Total   = " + Integer.toString(total), 25, 85);
        graf.drawString("Average = " + Double.toString(avg), 25, 100);
        graf.drawString("Median = " + Integer.toString(median), 25, 115);



    }
}
Run Code Online (Sandbox Code Playgroud)

lyn*_*nyi 63

Java中的Arrays类有一个静态排序函数,您可以调用它Arrays.sort(numArray).

Arrays.sort(numArray);
double median;
if (numArray.length % 2 == 0)
    median = ((double)numArray[numArray.length/2] + (double)numArray[numArray.length/2 - 1])/2;
else
    median = (double) numArray[numArray.length/2];
Run Code Online (Sandbox Code Playgroud)

  • @FBB他们给出了相同的结果.当长度为奇数时,我们输入else子句,因此对于某个整数"k",它是"2*k + 1".它的一半是`k + 0.5`,但是当它变成整数(因为它是一个数组索引)时,它变成了'k`. (8认同)
  • 我认为`else`子句应该是:`median =(double)numArray [(numArray.length - 1)/ 2];` (6认同)
  • 如果数组仅包含一个元素怎么办?您的代码将因超出范围的异常而崩溃。 (2认同)
  • @EldarAgalarov 如果数组只包含一个元素,为什么它会因越界异常而崩溃?长度为 1 是奇数,因此它会进入 else 情况,其中它尝试​​访问“numArray.length/2”处的元素。由于“numArray.length”为 1,因此它将索引计算为“1/2”,得出“0”。“0”是长度为 1 的数组的有效索引。 (2认同)

Bru*_*ist 34

对阵列进行排序是不必要且低效的.QuickSort(QuickSelect)算法有一个变体,它的平均运行时间为O(n); 如果你先排序,那么你就是O(n log n).它实际上找到了列表中的第n个最小项; 对于中位数,您只需使用n =列表长度的一半.我们称之为quickNth(list,n).

概念是找到第n个最小值,选择一个"枢轴"值.(具体如何选择它并不重要;如果您知道数据将是完全随机的,您可以选择列表中的第一项.)

将原始列表拆分为三个较小的列表:

  • 一个值小于枢轴的值.
  • 一个值等于枢轴的值.
  • 一个值大于枢轴的值.

然后你有三种情况:

  1. "较小"列表具有> = n项.在这种情况下,您知道第n个最小值在该列表中.返回quickNth(更小,n).
  2. 较小的列表具有<n项,但较小和相等列表的长度之和具有> = n项.在这种情况下,第n个等于"相等"列表中的任何项目; 你完成了.
  3. n大于较小和相等列表的长度之和.在这种情况下,您基本上可以跳过这两个,并相应地调整n.返回quickNth(更大,n - 长度(更小) - 长度(相等)).

完成.

如果您不确定数据是否完全随机,则需要更加精确地选择枢轴.取列表中第一个值的中位数,列表中的最后一个值,以及两个中间值之间的值非常好.

如果您选择枢轴非常不走运,并且总是选择最小或最高值作为枢轴,则需要O(n ^ 2)时间; 那很糟.但是,它也非常如果你选择一个体面的算法您的数据透视可能性不大.

示例QuickSelect代码

  • 很好的回答,但是指向实现的链接会使它变得更好。 (2认同)
  • 好主意.我编辑了原始链接到我编写的一些示例代码,使用ArrayLists而不是数组. (2认同)

Ani*_*rni 7

如果你想在这里使用任何外部库,那么Apache commons数学库可以用来计算中位数.
有关更多方法和用法,请参阅API文档

import org.apache.commons.math3.*;
.....
......
........
//calculate median
public double getMedian(double[] values){
 Median median = new Median();
 double medianValue = median.evaluate(values);
 return medianValue;
}
.......
Run Code Online (Sandbox Code Playgroud)

更新

在程序中计算

通常,使用此处给出的以下两个公式计算中值

如果n是奇数,那么中位数(M)=((n + 1)/ 2)项项的值.
如果n是偶数则中位数(M)= [((n)/ 2)项项的值+((n)/ 2 + 1)项项]/2

在您的程序中numArray,首先需要使用Arrays排序数组#sorted

Arrays.sort(numArray);
int middle = numArray.length/2;
int medianValue = 0; //declare variable 
if (numArray.length%2 == 1) 
    medianValue = numArray[middle];
else
   medianValue = (numArray[middle-1] + numArray[middle]) / 2;
Run Code Online (Sandbox Code Playgroud)


i_u*_*net 5

Arrays.sort(numArray);
return (numArray[size/2] + numArray[(size-1)/2]) / 2;
Run Code Online (Sandbox Code Playgroud)