Calculate median in c#

前端 未结 12 1429
别跟我提以往
别跟我提以往 2020-11-29 23:35

I need to write function that will accept array of decimals and it will find the median.

Is there a function in the .net Math library?

相关标签:
12条回答
  • 2020-11-30 00:09
    decimal Median(decimal[] xs) {
      Array.Sort(xs);
      return xs[xs.Length / 2];
    }
    

    Should do the trick.

    -- EDIT --

    For those who want the full monty, here is the complete, short, pure solution (a non-empty input array is assumed):

    decimal Median(decimal[] xs) {
      var ys = xs.OrderBy(x => x).ToList();
      double mid = (ys.Count - 1) / 2.0;
      return (ys[(int)(mid)] + ys[(int)(mid + 0.5)]) / 2;
    }
    
    0 讨论(0)
  • 2020-11-30 00:13

    My 5 cents (because it appears more straightforward/simpler and sufficient for short lists):

    public static T Median<T>(this IEnumerable<T> items)
    {
        var i = (int)Math.Ceiling((double)(items.Count() - 1) / 2);
        if (i >= 0)
        {
            var values = items.ToList();
            values.Sort();
            return values[i];
        }
    
        return default(T);
    }
    

    P.S. using "higher median" as described by ShitalShah.

    0 讨论(0)
  • Is there a function in the .net Math library?

    No.

    It's not hard to write your own though. The naive algorithm sorts the array and picks the middle (or the average of the two middle) elements. However, this algorithm is O(n log n) while its possible to solve this problem in O(n) time. You want to look at selection algorithms to get such an algorithm.

    0 讨论(0)
  • 2020-11-30 00:17

    Math.NET is an opensource library that offers a method for calculating the Median. The nuget package is called MathNet.Numerics.

    The usage is pretty simple:

    using MathNet.Numerics.Statistics;
    
    IEnumerable<double> data;
    double median = data.Median();
    
    0 讨论(0)
  • 2020-11-30 00:21

    Below code works: but not very efficient way. :(

    static void Main(String[] args) {
            int n = Convert.ToInt32(Console.ReadLine());            
            int[] medList = new int[n];
    
            for (int x = 0; x < n; x++)
                medList[x] = int.Parse(Console.ReadLine());
    
            //sort the input array:
            //Array.Sort(medList);            
            for (int x = 0; x < n; x++)
            {
                double[] newArr = new double[x + 1];
                for (int y = 0; y <= x; y++)
                    newArr[y] = medList[y];
    
                Array.Sort(newArr);
                int curInd = x + 1;
                if (curInd % 2 == 0) //even
                {
                    int mid = (x / 2) <= 0 ? 0 : (newArr.Length / 2);
                    if (mid > 1) mid--;
                    double median = (newArr[mid] + newArr[mid+1]) / 2;
                    Console.WriteLine("{0:F1}", median);
                }
                else //odd
                {
                    int mid = (x / 2) <= 0 ? 0 : (newArr.Length / 2);
                    double median = newArr[mid];
                    Console.WriteLine("{0:F1}", median);
                }
            }
    
    }
    
    0 讨论(0)
  • 2020-11-30 00:28

    Here's a generic version of Jason's answer

        /// <summary>
        /// Gets the median value from an array
        /// </summary>
        /// <typeparam name="T">The array type</typeparam>
        /// <param name="sourceArray">The source array</param>
        /// <param name="cloneArray">If it doesn't matter if the source array is sorted, you can pass false to improve performance</param>
        /// <returns></returns>
        public static T GetMedian<T>(T[] sourceArray, bool cloneArray = true) where T : IComparable<T>
        {
            //Framework 2.0 version of this method. there is an easier way in F4        
            if (sourceArray == null || sourceArray.Length == 0)
                throw new ArgumentException("Median of empty array not defined.");
    
            //make sure the list is sorted, but use a new array
            T[] sortedArray = cloneArray ? (T[])sourceArray.Clone() : sourceArray;
            Array.Sort(sortedArray);
    
            //get the median
            int size = sortedArray.Length;
            int mid = size / 2;
            if (size % 2 != 0)
                return sortedArray[mid];
    
            dynamic value1 = sortedArray[mid];
            dynamic value2 = sortedArray[mid - 1];
            return (sortedArray[mid] + value2) * 0.5;
        }
    
    0 讨论(0)
提交回复
热议问题