枚举的NSArray开始givven指数搜索两种方式(环绕)(Enumerate NSArray s

2019-10-17 14:52发布

例。 我有15个对象的数组。 我要开始从给定的索引枚举。 说开始于指数5,然后上面的指标之下,上方的指数,下等...我不希望它环绕。

所以在我的例子索引的顺序会。 5,6,4,7,3,8,2,9,1,10,0,11,14,12,13

这将是巨大的,有类似于下面的行的方法签名,但我不要求以approva一个答案:

- (void)enumerateFromIndex:(NSUInteger)index wrapAroundAndGoBothWays:(void (^)(id obj, NSUInteger idx, BOOL *stop))block

如何才能做到这一点? 想避免复制阵列等

在这篇文章中我们与周围没有包装做到这一点: 枚举的NSArray开始givven指数搜索两种方式(不回绕)

Answer 1:

从@omz借款,这里是包装变型,这是更简单:

@implementation NSArray (Extensions)

- (void)enumerateFromIndex:(NSUInteger)index wrapAroundAndGoBothWays:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
{
    BOOL stop = NO;
    NSUInteger actual = index;
    for (NSUInteger i = 0; i < self.count && !stop; i++) {
        actual += (2*(i%2)-1)*i;
        actual = (self.count + actual)%self.count;
        block([self objectAtIndex:actual], actual, &stop);
    }
}

@end


Answer 2:

这是一个数学问题。 有一个很好的解决方案。 然而,它涉及排序提前索引列表。

我们的想法是铺设从0到15整数出在圆上,并采取在它们出现在一轴线上顺序的元素。

由于在ObjC这样做是很繁琐,我提出了蟒蛇的解决方案:

from math import pi, cos

def circlesort(N, start):
    eps = 1e-8
    res = range(N)
    def f(x):
        return -cos(2*pi*(x-start-eps)/N)
    res.sort( lambda x,y:cmp(f(x), f(y)) )
    return res

然后

print circlesort(15, 5)

输出

[5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 14, 12, 13]

这是期望的结果。

编辑

好了,这是一个C实现:

#include <stdlib.h>
#include <math.h>
#define sign(x) ((x)>0?1:(x)<0?-1:0)

void circlesort(int* values, int N, int start){
    double f(int x)
    {
        return -cos(2*M_PI*((double)(x-start)-.25)/N);
    }
    int compare (const void * a, const void * b)
    {
        return sign( f(*(int*)a) - f(*(int*)b) );
    }
    qsort (values, N, sizeof(int), compare);
}

这将circlesort lenght N.使用像这样的整数数组:

int i, N = 15;
int indexes[N];
for (i=0;i<N;i++) 
    indexes[i] = i;
circlesort(indexes, N, 5);

现在该阵列indexes是在所希望的顺序进行排序。 因为有嵌套函数,你应该添加-fnested-functions编译器标志。

编辑2

考虑到这一事实,有一个更简单的解决方案(见我的其他回答)这个人是相当的学术。



文章来源: Enumerate NSArray starting at givven index searching both ways (wrap around)