【问题标题】:Finding the median value of an array?查找数组的中值?
【发布时间】:2010-09-11 17:33:24
【问题描述】:

我想知道是否可以找到数组的中值?例如,假设我有一个大小为 9 的数组。能找到这个数组的中间槽吗?

【问题讨论】:

  • 如果您对数组处理有所了解,那应该是非常简单的。请注意,除非数组已排序,否则中间槽不是中位数。这是作业吗?
  • Java 还是 C++?选一个。而且“中值”和“中槽”不是一回事,选一个吧。

标签: java c++ arrays


【解决方案1】:

假设数组 x 已排序且长度为 n

如果 n 为奇数,则中位数为 x[(n-1)/2]。
如果 n 比中位数为偶数,则为 ( x[n/2] + x[(n/2)-1] ) / 2。

【讨论】:

  • 这至少需要 o(nlogn) 时间。
  • 这实际上需要固定的时间
【解决方案2】:

如果你想在这里使用任何外部库是Apache commons math library,你可以计算Median
更多方法和使用请看API documentation

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

在程序中计算

一般情况下,中位数的计算使用以下两个公式given here

如果 n 是奇数,则中位数 (M) = 第 ((n + 1)/2) 项的值。
如果 n 为偶数,则中位数 (M) = [((n)/2)th item term + ((n)/2 + 1)th item term ]/2

这很容易,因为你有 9 个元素(奇数)。
查找数组的中间元素。
在你的程序中你可以声明数组

//as you mentioned in question, you have array with 9 elements
int[] numArray = new int[9]; 

那么你需要使用Arrays#sort对数组进行排序

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;

【讨论】:

    【解决方案3】:

    在 C++ 中,您可以使用std::nth_element;见http://cplusplus.com/reference/algorithm/nth_element/

    【讨论】:

      【解决方案4】:

      在java中:

      int middleSlot = youArray.length/2;
      yourArray[middleSlot];
      

      yourArray[yourArray.length/2];
      

      一行。

      这是可能的,因为在 java 中数组具有固定大小。

      注意: 3/2 == 1


      资源:

      【讨论】:

      • 你的答案是错误的。例如,考虑一个包含两个元素的数组:3 和 75。您的答案给出的中位数为 75。
      • {3, 75} 的中位数是多少
      • 梅森,你似乎把中位数和平均值混淆了。
      • @Gal,根据中位数的定义,如果值的个数是偶数,中位数是两个中间值的平均值。所以曼森是对的。
      【解决方案5】:
      vector<int> v;
      size_t len = v.size;
      nth_element( v.begin(), v.begin()+len/2,v.end() );
      
      int median = v[len/2];
      

      【讨论】:

        【解决方案6】:

        像专业人士一样在一行中完成:

        return (arr[size/2] + arr[(size-1)/2]) / 2;
        

        如果您期待 double 等,请转换为 double 等。

        【讨论】:

          【解决方案7】:

          上面的 Java 答案只有在有奇数数量的数字时才有效,这是我得到的解决方案的答案:

          if (yourArray.length % 2 == 0){
          
               //this is for if your array has an even ammount of numbers
               double middleNumOne = yourArray[yourArray.length / 2 - 0.5]
               double middleNumTwo = yourArray[yourArray.length / 2 + 0.5]
               double median = (middleNumOne + middleNumTwo) / 2;
               System.out.print(median);
          
          }else{
          
               //this is for if your array has an odd ammount of numbers
               System.out.print(yourArray[yourArray.length/2];);
          }
          

          请注意,这是一个概念证明,而且是即时的。如果你认为你可以让它更紧凑或更不密集,那就继续吧。请不要批评它。

          【讨论】:

            【解决方案8】:

            还有另一种选择——一般来说,这里的建议要么建议对数组进行排序,然后从这样的数组中获取中值,要么依赖于(外部)库解决方案。当今最快的排序算法平均而言是线性的,但在计算中值时可能会比线性算法做得更好。

            从未排序的数组中计算中位数的最快算法是QuickSelect,平均而言,它可以在与 O(N) 成正比的时间内找到中位数。该算法将数组作为参数,以及 int 值k(顺序统计,即数组中的第 k 个最小元素)。在这种情况下,k 的值只是 N/2,其中 N 是数组长度。

            实现起来有点棘手,但这里有一个示例,它依赖于Comparable&lt;T&gt; 接口和Collections.shuffle(),没有任何外部依赖。

            public final class QuickSelectExample {
            
                public static <T extends Comparable<? super T>> T select(T[] a, int k) {
                    if (k < 1) throw new IllegalStateException("Invalid k - must be in [1, inputLength].");
                    if (k > a.length) throw new IllegalStateException("K-th element exceeds array length.");
                    Collections.shuffle(Arrays.asList(a));
                    return find(a, 0, a.length - 1, k - 1);
                }
            
                private static <T extends Comparable<? super T>> T find(T[] a, int lo, int hi, int k) {
                    int mid = partition(a, lo, hi);
            
                    if (k == mid) return a[k];
                    else if (k < mid) return find(a, lo, mid - 1, k); // search left subarray
                    else if (k > mid) return find(a, mid + 1, hi, k); // search right subarray
                    else throw new IllegalStateException("Not found");
                }
            
                private static <T extends Comparable<? super T>> int partition(T[] a, int lo, int hi) {
                    T pivot = a[lo];
                    int i = lo + 1;
                    int j = hi;
            
                    while (true) { // phase 1
                        while (i <= hi && (less(a[i], pivot) || eq(a[i], pivot))) // is a[i] >= pivot?
                            i++;
            
                        while (j >= i && !less(a[j], pivot))  // is a[j] <= pivot?
                            j--;
            
                        if (i >= j) break;
                        exch(a, i, j);
                    }
                    exch(a, lo, j); // phase 2
                    return j;
                }
            
                private static <T extends Comparable<? super T>> boolean less(T x, T y) {
                    return x.compareTo(y) < 0;
                }
            
                private static <T extends Comparable<? super T>> boolean eq(T x, T y) {
                    return x.compareTo(y) == 0;
                }
            }
            

            代码为这些输入数组生成以下顺序统计信息:

                        "                  Input Array                    |                                                           Actual Output [format: (index k -> array element)]                                                           ", //
                        "                                                 |                                                                                                                                                                        ", //
                        "       [S, O, R, T, E, X, A, M, P, L, E]         |                            [(1 -> A), (2 -> E), (3 -> E), (4 -> L), (5 -> M), (6 -> O), (7 -> P), (8 -> R), (9 -> S), (10 -> T), (11 -> X)]                            ", //
                        "   [P, A, B, X, W, P, P, V, P, D, P, C, Y, Z]    |            [(1 -> A), (2 -> B), (3 -> C), (4 -> D), (5 -> P), (6 -> P), (7 -> P), (8 -> P), (9 -> P), (10 -> V), (11 -> W), (12 -> X), (13 -> Y), (14 -> Z)]           " //
            

            【讨论】:

              【解决方案9】:

              在 Java 的情况下,除以 2.0 足以将 int 转换为 double

               return n%2 == 0 ? (all[n/2] + all[n/2-1])/2.0 : all[(n-1)/2];
              

              第一个条件检查值是否为偶数。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-08-14
                • 2018-09-24
                • 1970-01-01
                相关资源
                最近更新 更多