2011-08-11 7 views
11

ソートされた配列を取得する必要はありません。ちょうどn番目の要素の値です。例えば、配列Javaの 'nth_element'と同等の機能は何ですか?

a = [20, 5, 1, -3] 

与えられた私はC++で

nth_element(a,2) = 1 

を照会できるようにしたいのですが、これを行うことができます機能std::nth_elementがあります。同等のJava関数はありますか?

ありがとうございます!

+1

あなたはこの方法で構築をお探しですか?いいえ、標準ライブラリには存在しません。 –

+1

@Justin - 彼は、配列がソートされていても、配列をソートする必要のないオーバーヘッドがなければ、n番目の要素を求めています。 C++には同等のSTLアルゴリズムがあります:http://cplusplus.com/reference/algorithm/nth_element/ – Dawson

+3

ここでは、可能な効率的なアルゴリズムについて説明します。彼らはまったく些細なことではありません。 http://stackoverflow.com/questions/251781/how-to-find-the-kth-largest-element-in-an-unsorted-array-of-length-n-in-on – mellamokb

答えて

5

Java標準ライブラリには、C++ nth_elementアルゴリズムと同等のものは含まれていません。あなたが得る最も近いものはCollections.sortです。

また、この機能の独自のバージョンを実装することもできます。標準の並べ替えを実行してCollections.sortを呼び出すことでnth_elementを実装できますが、これは時間要件によっては遅すぎる可能性があります。 選択アルゴリズムthe Wikipedia page on the subjectには、いくつかの良い例があります。この並べ替えを実行するための多くの特殊なアルゴリズムがあります。経験的に、最も速いアルゴリズムはquickselectと呼ばれ、クイックソートアルゴリズムに基づいています。予想されるO(n)時間に実行されますが、病理学的に不良な入力についてはO(n )に低下します。有名な(そして悪名高い複雑な)アルゴリズムがありますが、時には最悪の場合O(n)で実行されますが、実際に使用されることを妨げる高い定数係数を持つmedian-of-mediansアルゴリズムと呼ばれます。

希望すると便利です。

私はあなたが、このような何かを、それを実装するために持っていると思うJavaでは
0

:ここ

Integer nth_smallest_element(Integer[] originalArray, n) { 
    if (n >= originalArray.length) 
     throw new RuntimeException("Invalid index"); 
    // Don't pass in your array, if you don't want it to be modified. Instead add them all later. 
    List<Integer> copyList = new ArrayList<Integer>(); 
    copyList.addAll(originalArray); 
    Collections.sort(copyList); 
    return copyList.get(n); 
} 
+0

これは、しかし、ポイントを逃す。 'nth_smallest_element'はO(n)で行うことができますが、あなたの解は少なくともO(ng n)です。全体をソートする必要はありません。 – GManNickG

+0

nth_smallest_elementを得るために考えられる最良のアルゴリズムは、最悪の場合(例えば、200個のアイテムの中で100番目に小さいものを探す)、n * lg n - n/2 * lg n/2の比較を含みます。私は実際にO(n)でそれを行うより良い方法があるかどうかを知りたいと思う。並べ替えは少し高価ですが、よりクリーンで簡単です。 – n0rm1e

+1

彼らは「選択アルゴリズム」と呼ばれていますが、Wikipediaには[this thread]と同様の情報があります(http://stackoverflow.com/questions/251781/how-to-find-the-kth-largest-element-in-配列の長さがn-in-onである配列)。 – GManNickG

0

がnth_elementのJava実装である:

class Nth_element 
{ 
    static void nth_element_helper2(double[] arr, int beg, int end) 
    { 
     for(int i = beg + 1; i < end; i++) 
     { 
      for(int j = i; j > beg; j--) 
      { 
       if(arr[j - 1] < arr[j]) 
        break; 
       double t = arr[j]; 
       arr[j] = arr[j - 1]; 
       arr[j - 1] = t; 
      } 
     } 
    } 

    static void nth_element_helper(double[] arr, int beg, int end, int index) 
    { 
     if(beg + 4 >= end) 
     { 
      nth_element_helper2(arr, beg, end); 
      return; 
     } 
     int initial_beg = beg; 
     int initial_end = end; 

     // Pick a pivot (using the median of 3 technique) 
     double pivA = arr[beg]; 
     double pivB = arr[(beg + end)/2]; 
     double pivC = arr[end - 1]; 
     double pivot; 
     if(pivA < pivB) 
     { 
      if(pivB < pivC) 
       pivot = pivB; 
      else if(pivA < pivC) 
       pivot = pivC; 
      else 
       pivot = pivA; 
     } 
     else 
     { 
      if(pivA < pivC) 
       pivot = pivA; 
      else if(pivB < pivC) 
       pivot = pivC; 
      else 
       pivot = pivB; 
     } 

     // Divide the values about the pivot 
     while(true) 
     { 
      while(beg + 1 < end && arr[beg] < pivot) 
       beg++; 
      while(end > beg + 1 && arr[end - 1] > pivot) 
       end--; 
      if(beg + 1 >= end) 
       break; 

      // Swap values 
      double t = arr[beg]; 
      arr[beg] = arr[end - 1]; 
      arr[end - 1] = t; 

      beg++; 
      end--; 
     } 
     if(arr[beg] < pivot) 
      beg++; 

     // Recurse 
     if(beg == initial_beg || end == initial_end) 
      throw new RuntimeException("No progress. Bad pivot"); 
     if(index < beg) // This is where we diverge from QuickSort. We only recurse on one of the two sides. This is what makes nth_element fast. 
      nth_element_helper(arr, initial_beg, beg, index); 
     else 
      nth_element_helper(arr, beg, initial_end, index); 
    } 

    static double nth_element(double[] arr, int index) 
    { 
     nth_element_helper(arr, 0, arr.length, index); 
     return arr[index]; 
    } 

    public static void main(String[] args) 
    { 
     double[] arr = { 9, 7, 1, 5, 6, 4, 3, 2, 8, 0, 10 }; 
     if(nth_element(arr, 5) == 5) 
      System.out.println("seems to work"); 
     else 
      System.out.println("broken"); 
    } 
} 
関連する問題