这是一个数学问题。有一个很好的解决方案。但是,它涉及预先对索引列表进行排序。
这个想法是将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
考虑到有一个更简单的解决方案(参见我的另一个答案)这一事实,这个解决方案相当学术。