Обнаруживать последовательности чисел с допустимой погрешностью
У меня есть большой массив чисел с плавающей точкой. Эти цифры представляют отдельные высоты.
Как я могу обнаружить последовательности "похожих" чисел. Как и при нахождении того же номера с разницей, скажем, "меньше 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;
}
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]
]