Ruby中中值的计算

Ruby中中值的计算,ruby,median,Ruby,Median,如何使用Ruby计算数字数组的中值 我是一个初学者,在我的学习过程中,我试图坚持已经教过的东西。因此,我发现的其他问题超出了我的范围 以下是我的笔记和我的尝试: 按升序对数组排序 找出它的长度是奇数还是偶数 如果为奇数,则将排序后的数组长度+1减半。那个 是中位数的指数。返回此值 如果是偶数,则找到排序数组的中间两个数字,并将它们除以1/2。 返回此值 查找中间的两个数字: 将排序后的数组长度一分为二。这是索引pt。第一个中间数字 将排序的数组长度+2除以一半。这是指数pt。的 第二个中间数字

如何使用Ruby计算数字数组的中值

我是一个初学者,在我的学习过程中,我试图坚持已经教过的东西。因此,我发现的其他问题超出了我的范围

以下是我的笔记和我的尝试:

  • 按升序对数组排序
  • 找出它的长度是奇数还是偶数
  • 如果为奇数,则将排序后的数组长度+1减半。那个 是中位数的指数。返回此值
  • 如果是偶数,则找到排序数组的中间两个数字,并将它们除以1/2。 返回此值
  • 查找中间的两个数字:
  • 将排序后的数组长度一分为二。这是索引pt。第一个中间数字
  • 将排序的数组长度+2除以一半。这是指数pt。的 第二个中间数字
  • 取这两个中间数字的平均值

    def median(array)
      ascend = array.sort
      if ascend % 2 != 0
        (ascend.length + 1) / 2.0
      else
        ((ascend.length/2.0) + ((ascend.length + 2)/2.0) / 2.0)
      end
    end
    

  • 如果通过计算中位数,你的意思是

    然后


    以下是一种既适用于偶数长度数组又适用于奇数长度数组的解决方案,它不会改变数组:

    def median(array)
      return nil if array.empty?
      sorted = array.sort
      len = sorted.length
      (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
    end
    
    我觉得很好:

    #!/usr/bin/env ruby
    
    #in-the-middle value when odd or
    #first of second half when even.
    def median(ary)
      middle = ary.size/2
      sorted = ary.sort_by{ |a| a }
      sorted[middle]
    end
    


    我使用sort_而不是sort,因为它比sort更快:.

    类似于nbarraille的,但我发现它更容易跟踪这一方法的工作原理:

    class Array
      def median
        sorted = self.sort
        half_len = (sorted.length / 2.0).ceil
        (sorted[half_len-1] + sorted[-half_len]) / 2.0
      end
    end
    
    half_len=数组中间的元素数(对于项目数为奇数的数组)

    更简单的是:

    class Array
      def median
        sorted = self.sort
        mid = (sorted.length - 1) / 2.0
        (sorted[mid.floor] + sorted[mid.ceil]) / 2.0
      end
    end
    

    *如果长度为偶数,则必须将中点加上中点-1,以说明从0开始的索引,这是处理边缘情况的更正确解决方案:

      def median(array)                          #Define your method accepting an array as an argument. 
          array = array.sort                     #sort the array from least to greatest
          if array.length.odd?                   #is the length of the array odd?
            array[(array.length - 1) / 2] #find value at this index
          else array.length.even?                #is the length of the array even?
           (array[array.length/2] + array[array.length/2 - 1])/2.to_f
                                                 #average the values found at these two indexes and convert to float
          end
        end
    
    class Array
      def median
        sorted = self.sort
        size = sorted.size
        center = size / 2
    
        if size == 0
          nil
        elsif size.even?
          (sorted[center - 1] + sorted[center]) / 2.0
        else
          sorted[center]
        end
      end
    end
    
    有一个规范可以证明:

    describe Array do
      describe '#median' do
        subject { arr.median }
    
        context 'on empty array' do
          let(:arr) { [] }
    
          it { is_expected.to eq nil }
        end
    
        context 'on 1-element array' do
          let(:arr) { [5] }
    
          it { is_expected.to eq 5 }
        end
    
        context 'on 2-elements array' do
          let(:arr) { [1, 2] }
    
          it { is_expected.to eq 1.5 }
        end
    
        context 'on odd-size array' do
          let(:arr) { [100, 5, 2, 12, 1] }
    
          it { is_expected.to eq 5 }
        end
    
        context 'on even-size array' do
          let(:arr) { [7, 100, 5, 2, 12, 1] }
    
          it { is_expected.to eq 6 }
        end
      end
    end
    
    这里有一个解决方案:

    app_arry=[2,3,4,2,5,6,16]。排序
    #检查数组不为空
    如果app_arry.empty?|app_arry==“”
    放上“对不起,这行不通。”
    归零
    结束
    长度=app_arry.length
    放置“数组长度=#{length}”
    放置“数组=#{app_arry}”
    如果长度%2==0
    #偶数元素
    将“中位数为{(app#arry[length/2]。to#f+app#arry[(length-1)/2]。to#f)/2}”
    其他的
    #奇数元素
    将“中位数为#{app_arry[(长度-1)/2]}”
    结束
    
    输出

    数组长度=7

    数组=[2,3,4,2,5,6,16]

    中位数是2


    我喜欢使用改进,这是一种安全的方法,可以对ruby类进行Monkey Patch而不会对系统产生附带影响

    使用方法比新方法更干净

    使用,您可以对
    数组
    类进行猴子补丁,实现
    数组#中值
    ,此方法仅在使用优化的类的范围内可用:)

    改进
    模块阵列引用
    优化数组do
    def中位数
    如果为空,返回nil?
    排序
    (已排序[(长度-1)/2]+已排序[长度/2])/2.0
    结束
    结束
    结束
    类MyClass
    使用ArrayRefinems
    #你可以在这里随意使用数组中位数
    def测试(阵列)
    中位数数组
    结束
    结束
    MyClass.new.test([1,2,2,2,3])
    => 2.0
    
    实际问题是什么?以下是问题:编写一个中值方法,将一组数字作为输入并返回中值。我的意思是你的问题是什么。当问问题时,你需要描述应该发生什么,发生了什么偏离预期的事情,以及你尝试了什么。是的,偶数第一使它成为一个if。。。else程序(在我目前所学的内容中)不必有if/else,请参阅我的回答需要
    2.0
    to_f
    以使类似4.5的结果成为可能。此外,最后一行应该是
    元素。偶数?(a[center]+a[center-1])/2.0:a[center]
    (注意
    a[center-1]
    中的负号和
    2.0
    ),否则偶数长度数组的中值在数组中偏移1个索引位置。使用2值数组尝试原始代码,您将得到一个错误。这只咬了我一口……这很有帮助。谢谢我理解这一点。
    类数组def median sorted=self.sort。。。结束
    <代码>[3,1,4,1,6]。中值
    如果数组为空,则返回0。空?
    @ArtemKalinchuk为什么为0?对于空数组,未定义中值。我同意应该改进这个方法来处理这种情况,或者返回类似于
    Float::NAN
    的内容,或者引发一个自定义的、更明确的错误。有很多方法可以做到这一点,但您的答案是最优雅的。非常清楚发生了什么。如果array.length不是奇数,那么它是偶数,或者它可能是其他东西吗?是否需要在else之后的表达式?是否也需要返回?我认为也不需要偶数计算。使用
    array.sort不是一个好主意,因为它会更改参数
    
      def median(array)                          #Define your method accepting an array as an argument. 
          array = array.sort                     #sort the array from least to greatest
          if array.length.odd?                   #is the length of the array odd?
            array[(array.length - 1) / 2] #find value at this index
          else array.length.even?                #is the length of the array even?
           (array[array.length/2] + array[array.length/2 - 1])/2.to_f
                                                 #average the values found at these two indexes and convert to float
          end
        end
    
    class Array
      def median
        sorted = self.sort
        size = sorted.size
        center = size / 2
    
        if size == 0
          nil
        elsif size.even?
          (sorted[center - 1] + sorted[center]) / 2.0
        else
          sorted[center]
        end
      end
    end
    
    describe Array do
      describe '#median' do
        subject { arr.median }
    
        context 'on empty array' do
          let(:arr) { [] }
    
          it { is_expected.to eq nil }
        end
    
        context 'on 1-element array' do
          let(:arr) { [5] }
    
          it { is_expected.to eq 5 }
        end
    
        context 'on 2-elements array' do
          let(:arr) { [1, 2] }
    
          it { is_expected.to eq 1.5 }
        end
    
        context 'on odd-size array' do
          let(:arr) { [100, 5, 2, 12, 1] }
    
          it { is_expected.to eq 5 }
        end
    
        context 'on even-size array' do
          let(:arr) { [7, 100, 5, 2, 12, 1] }
    
          it { is_expected.to eq 6 }
        end
      end
    end
    
    def median(arr)
        sorted = arr.sort 
        if sorted == []
           return nil
        end  
    
        if sorted.length % 2 != 0
           result = sorted.length / 2 # 7/2 = 3.5 (rounded to 3)
           return sorted[result] # 6 
        end
    
        if sorted.length % 2 == 0
           result = (sorted.length / 2) - 1
           return (sorted[result] + sorted[result+1]) / 2.0 #  (4 + 5) / 2
        end
    end
    
    p median([5, 0, 2, 6, 11, 10, 9])
    
    def median(array, already_sorted=false)
        return nil if array.empty?
        array = array.sort unless already_sorted
        m_pos = array.size / 2
        return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos])
    end