0

私は浮動小数点数の巨大な配列を持っています。これらの数値は特定のピッチを表します。

「類似した」数字のシーケンスを検出するにはどうすればよいですか? たとえば、「10 未満」の差がある同じ数を見つける場合と同様です。

たとえば、私のリストは次のようになります。

0:1000
1:2100
2:2000
3:440  
4:440
5:430
6:450
7:440
8:435
9:445
10:90
11:200
12:10
13:50
14:16
15:880
16:885
16:880
17:870
18:875

インデックス 3 から 9 までのエントリは非常に似ています (最大 10 の違い)。同様に、インデックス 15 ~ 18 は非常に似ています。

このような配列を処理して、同様の数値の各グループのインデックスを示す出力を取得するにはどうすればよいでしょうか。

例えば:

Sequence 1 : Start index = 3  End Index=9
Sequence 2 : Start index = 15  End Index=18

編集1:

これを行う最初の試みは、リストが作成されているときに行うことでした。5 つのインデックス長の配列がありました。処理中の次の数値が誤差の範囲内にある場合は、それをこの配列に追加します。配列がいっぱいになると、シーケンスができました。これは機能しますが、非常に柔軟性がありません。シーケンスは配列の長さよりも長く続く可能性があり、私はそれについて知りません。

float dominant=bin*(THIS->samplerate/bufferCapacity);



        float closestFloat=FREQ_WITHIN_RANGE;

        concurrent_note.currentfrequency=dominant;

        int index= concurrent_note.count;

        float lastfreq=concurrent_note.frequencylist[index];

        float check=fabsf(lastfreq-concurrent_note.currentfrequency);

        concurrent_note.frequencylist[index]=dominant;



        if (check<=closestFloat) {



            concurrent_note.currentfrequency=dominant;

            concurrent_note.frequencylist[concurrent_note.count]=dominant;

            concurrent_note.count++;

            if (concurrent_note.count>=CONSECTUTIVE_SIMILAR_FREQ_THRESHOLD) {

                //it is likely this is the same note



                float averagenote=0;

                for (int i=0; i<CONSECTUTIVE_SIMILAR_FREQ_THRESHOLD; i++) {

                    float note=concurrent_note.frequencylist[i];

                    averagenote+=note;

                    concurrent_note.frequencylist[i]=0;



                }

                averagenote=averagenote/CONSECTUTIVE_SIMILAR_FREQ_THRESHOLD;

                [THIS frequencyChangedWithValue:averagenote attime:(inTimeStamp->mSampleTime-fft.starttime) ];

                concurrent_note.count=0;

            }



        }else

        {

            concurrent_note.count=0;

        }
4

1 に答える 1

1

あなたのプログラムの構造がどのようなものか分からないので、私の答えを疑似コードとして提供しました:

var THRESHOLD = 10;
var compareElement = getFirstElement();

var Array<Element> currentArrayOfSimilarElements;
var Array<Array<Element>> arrayOfSimilarElements;


for (int i = 1; i < list.length(); i++)   //Start at element one
{
    var element;
    while( abs((element = list.objectAt(i)) - compareElement) < THRESHOLD)   //While elements are within the threshold
    {
        currentArrayOfSimilarElements.add(element);  //Add them to an array
        i++; //And increase the index
    }
    compareElement = element;  //We have a new object to compare to
    arraysOfSimilarElements.add(currentArrayOfSimilarElements); //Add the block of similar elements we found
    currentArrayOfSimilarElements.removeAll(); //And remove the elements from the block
}

同様の要素のブロックの配列が残ります。

[
    [440, 440, 430, 450, 440, 435, 445],
    [880, 885, 880]
]
于 2012-02-28T17:27:51.607 に答える