Reputation: 1214
I have an NSArray of 100 numbers. I would like to create an NSArray of 5 numbers. The first number in the second array is the average of the first 20 numbers in the first array. The second number is the average of the second set of 20 numbers in the first array. And so on.
I'm curious to hear people's ideas for an efficient algorithm.
One idea I had was to do a for-loop on each set of 20 numbers, creating a temp NSArray of 20 numbers. Then perform a KVO average operation and add to the final NSArray.
Note: I always award THE answer to someone, and I'm not shy to up vote your answers. I encourage many answers. Thanks!
Upvotes: 1
Views: 221
Reputation: 24031
you could try something like this...
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])];
the _averages
will contain 5 values with the averages of the five different sections of the 100 numbers.
UPDATED:
this part is just for eyes with extra curiosity.
if you tries to avoid the NSObjects
and the double for
loops, you could achieve a really fast algorithm, and of course when you go lower levels, you can improve the current speed as well, the question is: does it really need?
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;
}
it is 10 times faster than the solution with double
for loops and NSObject
classes.
(un)fortunately, it is not even the ugliest solution, but there is no question it is fast as hell, I won't recommend it except the speed really matter because that kind of solutions can provide really good efficiency.
Upvotes: 1
Reputation: 112855
Just add the values in each 20 number section, divide by 20 and put in the appropriate output array location. It is one pass through the array, Big O(n), what more could you ask for? The time to compute this is minuscule.
Upvotes: 2
Reputation: 318874
The following is simple and efficient:
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);
Upvotes: 1