float 値の配列があり、その値と、さらに重要なことに最大 4 つの値の位置が必要です。
私は元々、現在の位置の値を記録された max-so-far と比較し、max-so-far が変化したときに位置変数を更新することによって、配列をウォークスルーし、通常の方法で max を見つけるシステムを構築しました。これは非常に単純な O(n) アルゴリズムで、うまく機能しました。上位の値だけでなく、上位 3 つまたは 4 つの値を保持する必要があることを後で知りました。同じ手順を拡張し、max-so-far を 4 つの max-so-fars の配列に複雑化したところ、コードが見苦しくなってしまいました。
手続きにわずかな量の計算しか追加されていないため、それでも機能し、十分に高速です。それでも効果的に配列全体を歩き回り、各値を 1 回チェックします。
これは、並べ替えられたリストとそれに付随する元の位置リストの 2 つの配列を返す並べ替え関数を使用して、MATLAB で行います。最初のいくつかの値を見ると、まさに必要なものが得られます。この機能を C# .NET 2.0 プログラムに複製しています。
List オブジェクトで同様のことができることと、List オブジェクトにはソート ルーチンが組み込まれていることは知っていますが、それが元の位置を教えてくれるとは思えません。
それはうまく機能していますが、今では 5 番目の最大値が必要であり、現在 if ステートメントの醜い混乱である max-so-far チェッカーを書き直すと、醜さを悪化させるだけであることがわかります。5 番目のレベルを追加しても問題なく動作し、遅くはありませんが、より良い方法があるかどうか SO コミュニティに尋ねたいと思います。
リスト全体をソートするには、現在の方法よりも多くの計算が必要ですが、リストは 1 千または 2 千の float しかないため、問題になるとは思いません。したがって、元の位置に戻すことができる並べ替えルーチンがあれば、それが理想的です。
背景として、この配列は 1 キロバイトの wave ファイルに対するフーリエ変換の結果であるため、最大値の位置はサンプル データのピーク周波数に対応します。私は上位 4 つに満足していましたが、より正確なサンプル分類を行うには、上位 5 つまたは 6 つを実際に収集する必要があると考えています。