13

リストがあります:

List<double> final=new List<double>();
final.Add(1);
final.Add(2);
final.Add(3);

このリストのモードを見つけるには、どのような方法を使用できますか? また、2 つのモードがある場合、関数は 2 つのうち小さい方を返します。

4

4 に答える 4

5

usr によって与えられた答えはうまくいくようですが、Linq 以外のものが必要な場合は、これを試してください。

    public int? FindMode(List<int> sample)
    {
        if (sample == null || sample.Count == 0)
        {
            return null;
        }

        List<int> indices = new List<int>();
        sample.Sort();

        //Calculate the Discrete derivative of the sample and record the indices
        //where it is positive.
        for (int i = 0; i < sample.Count; i++)
        {
            int derivative;

            if (i == sample.Count - 1)
            {
                //This ensures that there is a positive derivative for the
                //last item in the sample. Without this, the mode could not
                //also be the largest value in the sample.
                derivative = int.MaxValue - sample[i];
            }
            else
            {
                derivative = sample[i + 1] - sample[i];
            }

            if (derivative > 0)
            {
                indices.Add(i + 1);
            }
        }

        int maxDerivative = 0, maxDerivativeIndex = -1;

        //Calculate the discrete derivative of the indices, recording its
        //maxima and index.
        for (int i = -1; i < indices.Count - 1; i++)
        {
            int derivative;

            if (i == -1)
            {
                derivative = indices[0];
            }
            else
            {
                derivative = indices[i + 1] - indices[i];
            }

            if (derivative > maxDerivative)
            {
                maxDerivative = derivative;
                maxDerivativeIndex = i + 1;
            }
        }

        //The mode is then the value of the sample indexed by the
        //index of the largest derivative.
        return sample[indices[maxDerivativeIndex] - 1];
    }

私がここで行ったことは、本質的に、ウィキペディアのページの「サンプルのモード」セクションで説明されているアルゴリズムの実装です。最初にサンプルを並べ替えると、マルチモードの場合は小さい方のモードが返されることに注意してください。

また、Wikipedia ページの Octave コードは、1 ベースのインデックス付けを前提としています。C# は 0 ベースであるため、補正するためにindices.Add(i + 1)andを使用したことがわかります。maxDerivativeIndex = i + 1同じ理由でindices[maxDerivativeIndex] - 1、最終モードを返すときに 0 ベースのインデックスにマップし直すこともありました。


この方法は、a を使用しDictionaryてカウントを累積する直観的な方法よりも少しわかりにくいため、ここに一種の実用的な例を示します。

上記のメソッドを呼び出す:

int? mode = FindMode(new List<int>(new int[] { 1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17 }));

最初のチェックと並べ替えの後、最初の for ループの最後で、離散導関数 (つまり、indicesリスト) は次のようになります。

[1, 2, 6, 8, 10, 11]

次に、 の離散導関数を計算しindicesます。効率上の理由から、これらをリストに格納していません (最終的には最大のものだけが必要です) が、次のようになります。

[1, 1, 4, 2, 2, 1]

したがって、maxDerivative最終的には 4 とmaxDerivativeIndex2 になります。

sample[indices[maxDerivativeIndex] - 1]
    -> sample[indices[2] - 1]
    -> sample[6 - 1]
    -> 6
于 2014-01-15T07:08:49.337 に答える