1

例。15個のオブジェクトを含む配列があります。与えられたインデックスから列挙を始めたい。インデックス5から始めて、次に上のインデックス、下のインデックス、上、下など...ラップアラウンドしたいとします。

したがって、私の例のインデックスの順序は次のようになります。5、6、4、7、3、8、2、9、1、10、0、11、14、12、13

次の行のようなメソッドシグネチャがあると便利ですが、回答を承認するためにそれを要求する必要はありません。

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

これはどのように行うことができますか?アレイなどのコピーは避けたい。

この投稿では、ラップアラウンドなしでそれを行います:両方の方法で検索するgivvenインデックスから始まるNSArrayを列挙します(ラップアラウンドなし)

4

2 に答える 2

2

@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
于 2013-01-16T13:44:13.107 に答える
1

これは数学の問題です。良い解決策があります。ただし、事前にインデックスのリストを並べ替える必要があります。

アイデアは、0から15までの整数を円に配置し、軸に表示される順序で要素を取得することです。

ObjCでこれを行うのはとても面倒なので、Pythonソリューションを紹介します。

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);
}

これにより、長さ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

はるかに単純な解決策があるという事実を考えると(私の他の答えを参照)、これはかなり学術的です。

于 2013-01-16T10:34:30.740 に答える