What is the right approach when using STL container for median calculation?

后端 未结 10 934
再見小時候
再見小時候 2020-12-02 10:17

Let\'s say I need to retrieve the median from a sequence of 1000000 random numeric values.

If using anything but std::list, I have no (

10条回答
  •  Happy的楠姐
    2020-12-02 11:02

    The median is more complex than Mike Seymour's answer. The median differs depending on whether there are an even or an odd number of items in the sample. If there are an even number of items, the median is the average of the middle two items. This means that the median of a list of integers can be a fraction. Finally, the median of an empty list is undefined. Here is code that passes my basic test cases:

    ///Represents the exception for taking the median of an empty list
    class median_of_empty_list_exception:public std::exception{
      virtual const char* what() const throw() {
        return "Attempt to take the median of an empty list of numbers.  "
          "The median of an empty list is undefined.";
      }
    };
    
    ///Return the median of a sequence of numbers defined by the random
    ///access iterators begin and end.  The sequence must not be empty
    ///(median is undefined for an empty set).
    ///
    ///The numbers must be convertible to double.
    template
    double median(RandAccessIter begin, RandAccessIter end) 
      throw(median_of_empty_list_exception){
      if(begin == end){ throw median_of_empty_list_exception(); }
      std::size_t size = end - begin;
      std::size_t middleIdx = size/2;
      RandAccessIter target = begin + middleIdx;
      std::nth_element(begin, target, end);
    
      if(size % 2 != 0){ //Odd number of elements
        return *target;
      }else{            //Even number of elements
        double a = *target;
        RandAccessIter targetNeighbor= target-1;
        std::nth_element(begin, targetNeighbor, end);
        return (a+*targetNeighbor)/2.0;
      }
    }
    

提交回复
热议问题