2013-02-17 5 views
1

У меня есть NSArray из 100 чисел. Я хотел бы создать NSArray из 5 чисел. Первое число во втором массиве - это среднее из первых 20 чисел в первом массиве. Второе число - это среднее значение второго набора из 20 чисел в первом массиве. И так далее.Взять среднее количество сегментов NSArray

Мне любопытно слышать идеи людей для эффективного алгоритма.

Одна из моих идей заключалась в том, чтобы сделать цикл for для каждого набора из 20 чисел, создав тем самым NSArray из 20 чисел. Затем выполните среднюю операцию KVO и добавьте к окончательному NSArray.

Примечание: Я всегда награждаю ответ кому-то, и я не стесняюсь проголосовать за ваши ответы. Я призываю много ответов. Благодаря!

+3

Я полностью пропустил пункт использования KVO здесь .... – Till

+3

Это просто - напишите код. Любая «причудливая» схема, которую вы можете придумать с помощью KVO или чего-то еще, гарантированно будет медленнее и неяснее. Если это не вход в конкурс нечеткого кода или некоторые такие, просто напишите код! –

+0

@ Похоже, maddy просто объяснил мне, что KVO - это не то же самое, что кодирование с ключом. Теперь я понимаю ваш комментарий. Спасибо за ваш комментарий. –

ответ

1

Следующая является простым и эффективным:

NSArray *numbers = ... // array of 100 numbers 
NSMutableArray *averages = [NSMutableArray array]; 

for (int = 0; i < 5; i++) { 
    float total = 0.0; 
    int base = i * 20; 
    for (int j = 0; j < 20; j++) { 
     float num = [numbers[base + j] floatValue]; 
     total += num; 
    } 

    float avg = total/20.0f; 
    [averages addObject:@(avg)]; 
} 

NSLog(@"Averages = %@", averages); 
+1

Когда дело доходит до эффективности, можно немного выиграть, опуская умножение на 20 во внутреннем цикле. Не сложно понять, как это сделать ... – Till

+1

Еще один момент: вы используете двойное значение для разделения, меняете обозначение на 20.0f, чтобы избавиться от другого неявного типа. – Till

+1

@Zaph '@ (avg)' является сокращением для '[NSNumber numberWithFloat: avg]'. – rmaddy

2

Просто добавьте значения в каждом разделе 20 чисел, разделите их на 20 и поместите в соответствующее расположение выходного массива. Это один проход через массив Big O (n), о чем еще вы могли бы попросить? Время вычислить это незначительно.

1

вы могли бы попробовать что-то вроде этого ...

NSArray *_array = // with the 100 numbers... (I used NSNumber object for each number) 

NSMutableArray *_averages = [NSMutableArray array]; 
for (int i = 0; i < 5; i++) [_averages addObject:@([[[_array subarrayWithRange:NSMakeRange(i * 20, 20)] valueForKeyPath:@"@avg.floatValue"] floatValue])]; 

в _averages будет содержать 5 значений со средними из пяти различных секций 100 номеров.

ОБНОВЛЕНО:

эта часть просто для глаз с дополнительным любопытством.

если вы пытаетесь избежать NSObjects и двойную for петли, вы могли бы достичь действительно быстрого алгоритма, и, конечно же, когда вы идете более низкие уровни, вы можете улучшить текущую скорость, а также, вопрос: делает это действительно нужно?

NSInteger _segments = 1000; // it means 20.000 numbers; 
Float64 _numbers[(_segments * 20)]; // fill this array as you'd like. 

Float64 _averages[_segments]; 

for (int i = 0; i < _segments; i++) { 
    NSInteger _offset = (_segments<<4)+4; 
    _averages[i] = (_numbers[_offset] + _numbers[_offset+1] + _numbers[_offset+2] + _numbers[_offset+3] + _numbers[_offset+4] + _numbers[_offset+5] + _numbers[_offset+6] + _numbers[_offset+7] + _numbers[_offset+8] + _numbers[_offset+9] + _numbers[_offset+10] + _numbers[_offset+11] + _numbers[_offset+12] + _numbers[_offset+13] + _numbers[_offset+14] + _numbers[_offset+15] + _numbers[_offset+16] + _numbers[_offset+17] + _numbers[_offset+18] + _numbers[_offset+19])/20.f; 
} 

это в 10 раз быстрее, чем решение с double для петель и NSObject классов.

(ООН), к счастью, это даже не самое уродливое решение, но нет никаких сомнений, что это быстро, как ад, я не буду рекомендовать его кроме скорости действительно дела, потому что такого рода решения может обеспечить действительно хорошая эффективность.

+1

@eddieios Это не KVO (наблюдение за ключом), это ключевое значение. – rmaddy

+1

FYI - Я профилировал это решение против того, что было в моем ответе. Конечно, это решение было достаточно быстрым, если у вас всего 100 номеров, и вы не делаете расчет больше, чем несколько раз. – rmaddy

+0

@maddy, вы просто научили меня 3 что делает меня лучшим программистом. Благодарю. Я также благодарю вас за то, что вы потратили время на профайл кода. Мне очень нравятся ваши ответы. Pls продолжает следить и отвечать на мои вопросы, и я обязательно проголосую за ваши ответы. Еще раз спасибо. –

Смежные вопросы