Algorithm 查找数组中角度之间的最大差异
我正在处理一些加速度计数据,它是一个介于-180和180之间的值数组。用度表示角度Algorithm 查找数组中角度之间的最大差异,algorithm,math,accelerometer,Algorithm,Math,Accelerometer,我正在处理一些加速度计数据,它是一个介于-180和180之间的值数组。用度表示角度 有没有一个聪明的算法可以找出任意两个角度之间的最大差异?为了解决这个问题,应该有很多角度。当然,你可以打败O(n^2) 对数组进行排序。使用指针a和b逐步完成。首先找到与a形成最大角度的b,并将其存储到best。然后重复将a向前推进一步,然后执行b,直到停止增加差值。由于b无法跨过a,因此您将遍历该列表大约1.5倍的总和,以O(n)为界。因此,排序所需的时间并不比排序所需的时间更糟糕。为了担心这一点,应该有很多角
有没有一个聪明的算法可以找出任意两个角度之间的最大差异?为了解决这个问题,应该有很多角度。当然,你可以打败O(n^2)
对数组进行排序。使用指针
a
和b
逐步完成。首先找到与a
形成最大角度的b
,并将其存储到best
。然后重复将a
向前推进一步,然后执行b
,直到停止增加差值。由于b
无法跨过a
,因此您将遍历该列表大约1.5倍的总和,以O(n)为界。因此,排序所需的时间并不比排序所需的时间更糟糕。为了担心这一点,应该有很多角度。当然,你可以打败O(n^2)
对数组进行排序。使用指针
a
和b
逐步完成。首先找到与a
形成最大角度的b
,并将其存储到best
。然后重复将a
向前推进一步,然后执行b
,直到停止增加差值。由于b
无法跨过a
,因此您将遍历该列表大约1.5倍的总和,以O(n)为界。因此,它并不比排序所需的时间差。假设角度在[0,180]时为正,如果在[-180,0]时为负
扫描列表,执行以下操作:1记录最大和最小正角度
2记录最大和最小负角度
3如果一个角度是正角度,将其转换(让它减去180)为负角度,并用一些标志标记它以指示它来自转换 对于#1,最大的差异就是最大角度减去最小角度。#2也是如此 对于#3,首先对角度进行排序。从已排序列表的末尾扫描。如果相邻角度的类型不同(一个是转换角度,一个不是),则计算差异。如果差异是有史以来最小的,记录下来,然后继续扫描。完成后,使用180-差,结果为差#3 现在您有3个差异,选择最大的一个。我想这就是答案
对于复杂性,所有扫描都是O(n)。对于排序,如果所有角度都为正或负,则根本不需要相位#3。如果需要相位#3,我们可以让它有更小的角度。例如,如果列表的正角度较少,则可以将正角度转换为负角度,反之亦然。排序是O(nlgn),但我们可以有更小的n。如果角度在[0,180]中,它是正的,如果在[-180,0]中,它是负的 扫描列表,执行以下操作:
1记录最大和最小正角度
2记录最大和最小负角度
3如果一个角度是正角度,将其转换(让它减去180)为负角度,并用一些标志标记它以指示它来自转换 对于#1,最大的差异就是最大角度减去最小角度。#2也是如此 对于#3,首先对角度进行排序。从已排序列表的末尾扫描。如果相邻角度的类型不同(一个是转换角度,一个不是),则计算差异。如果差异是有史以来最小的,记录下来,然后继续扫描。完成后,使用180-差,结果为差#3 现在您有3个差异,选择最大的一个。我想这就是答案
对于复杂性,所有扫描都是O(n)。对于排序,如果所有角度都为正或负,则根本不需要相位#3。如果需要相位#3,我们可以让它有更小的角度。例如,如果列表的正角度较少,则可以将正角度转换为负角度,反之亦然。排序是O(nlgn),但我们可以有更小的n。从RW教程中得到了这一点 它与您想要的相反(返回最小角度),但您可以调整它
// Returns shortest angle between two angles,
// between -M_PI and M_PI
static inline CGFloat ScalarShortestAngleBetween(const CGFloat a, const CGFloat b)
{
CGFloat difference = b - a;
CGFloat angle = fmodf(difference, M_PI * 2);
if (angle >= M_PI)
{
angle -= M_PI * 2;
}
return angle;
}
这是从RW教程中得到的 它与您想要的相反(返回最小角度),但您可以调整它
// Returns shortest angle between two angles,
// between -M_PI and M_PI
static inline CGFloat ScalarShortestAngleBetween(const CGFloat a, const CGFloat b)
{
CGFloat difference = b - a;
CGFloat angle = fmodf(difference, M_PI * 2);
if (angle >= M_PI)
{
angle -= M_PI * 2;
}
return angle;
}
聪明?你的意思是对它们进行排序,然后取a[1]和a[N]数据是循环的,180=-180。因此,仅找到最小值和最大值是不够的。因此,请先转换,然后排序。定义“最大差异”?例如,角度X和角度X之间最大的区别是什么?是0吗?是360吗?它是360的特定整数倍吗?角度X和它本身之间的差是0。我们正在寻找一对相距最接近180度的组合(因为不可能得到更多)。聪明吗?你的意思是对它们进行排序,然后取a[1]和a[N]数据是循环的,180=-180。因此,仅找到最小值和最大值是不够的。因此,请先转换,然后排序。定义“最大差异”?例如,角度X和角度X之间最大的区别是什么?是0吗?是360吗?它是360的特定整数倍吗?角度X和它本身之间的差是0。我们正在寻找最接近180度的一对(因为不可能得到更多)。我认为你在这里得到了正确的答案,但需要更多的解释来将其与“排序并选择第一个和最后一个”建议分开。例如,您可以说明为什么对于排序数组
a
,如果a[j]
与a[i]
的角度差最大,a[k]
与a[i+1]
的角度差最大,k>=j
。这就是为什么你不必搜索O(n^2)对。我认为你在这里得到了正确的答案,但需要更多的解释才能将其与“排序并选择第一个和最后一个”建议分开。例如,您可以说明为什么对于排序数组a
,如果a[j]
的角度最大