我想借助附图中描述的系统计算数字之间的距离。如何计算C++中的数字之间的距离?
例如:7和5之间的距离为-2,7和1之间的距离是2等...
任何想法如何在C为此++?首选的方向是逆时针... 我正在使用(int)向量。
我想借助附图中描述的系统计算数字之间的距离。如何计算C++中的数字之间的距离?
例如:7和5之间的距离为-2,7和1之间的距离是2等...
任何想法如何在C为此++?首选的方向是逆时针... 我正在使用(int)向量。
如果你这样做的简单的方法(通过考虑所有可能性),它可能如下
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = b - a;
return
a <= b ?
(d <= +4 ? d : d - 8) :
(d <= -4 ? d + 8 : d);
}
,如果你愿意,可以改写为
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = b - a;
return -4 < d && d <= 4 ? d : (d > 0 ? d - 8 : d + 8);
}
的替代的更优雅的方法是总是计算正的CCW距离并且如果其大于4则将其翻转为负的CW距离
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = (b + 8 - a) % 8;
// `d` is CCW distance from `a` to `b`
return d <= 4 ? d : d - 8;
}
但是如果你想编译器产生这种情况的最有效的代码,遵循的金科玉律“使用无符号类型到处都可以使用符号类型只有当你要”:
int distance(unsigned a, unsigned b)
{ // Distance from `a` to `b`
unsigned d = (b + 8 - a) % 8;
// `d` is CCW distance from `a` to `b`
return d <= 4 ? d : (int) d - 8;
}
非常感谢您的精彩回答!它真的帮了我很多! – Engo
我有点不确定在这里应该实现'unsigned'的转换。给定范围内的输入似乎是严格不必要的。 –
@Dietrich Epp:通过使用'unsigned'类型,我们向编译器传递了一些关键信息。切换到'unsigned'类型允许编译器为'(b + 8 - a)%8'表达式生成更高效的代码,因为只要类型是'unsigned',这个表达式的语义就相当于你的' (b - a)&7'。举一个例子,GCC只要使用'unsigned'类型就会生成相同的代码。划分下的“签名”类型的语义是非常不同的,这导致更复杂和更低效的机器码。 – AnT
我认为这应该
int func(a,b)
{
dist=(b-a);
if(dist<0)
dist +=8;
return dist;
}
在你真的坚持
不适用于'func(0,4)',返回12,而不是4. –
@Timothy Higinbottom:对于'func(0,4)',它实际上工作正常并返回'4'。但它不符合其他要求。 – AnT
@安:真的,对不起,我的错误 –
为了简单起见情况下,你可以从std::find找到元素,并从获得从开始的距离std::distance
例如 正如你所提到的数据保存在INT矢量
std::vector<int>::iterator it1 = std::find(myvec.begin(), myvec.end(), val_1);
std::vector<int>::iterator it2 = std::find(myvec.begin(), myvec.end(), val_2);
int dist = std::distance(myvec.begin(),it1) - std::distance(myvec.begin.it2);
if(dist < 0) return dist
else(dist > 0) return myvector.size() - dist()
所以希望这会给距离图像...
我敢肯定,这个工程:
list = [0,1,2,3,4,5,6,7]
distance(x,y) {
a = y-x
b = length(list)-abs(y-x)
z = min(abs(a), abs(b))
if(z=abs(a)) { return a }
if(z=abs(b)) { return b }
}
其中abs()
是数学绝对值函数。
我在这里做一些假设。
正如@HédiGhédiri指出的那样,你不是在逆时针计数。我假设你算数的最短路径。 (我用数学min()
函数)
你更喜欢正值超过负值(@哈珀的评论)。如果您偏好负值,请切换最后两个if
语句。
可能有一个更简洁的方法,但这(希望)的作品。请评论,如果它是错误的。希望这有帮助!
编辑:这是psuedocode。用C++编写应该很容易。使用<stdlib.h>
中的abs()
函数忘记list
和length(list)
。对变量使用int
类型,其他所有内容都应该有效。
谢谢你的伪代码! – Engo
的以下代码准备满足您的所有需求,例如我假设,如果方向为顺时针,则距离为负。
#include <iostream>
#define RING_SIZE 8
enum direction
{
clockwise,
counterClockwise
};
int distance(int a, int b, direction dir)
{
int dist;
if(dir == clockwise)
{
if(a>b)
{
dist = -(a-b);
}
else
{
dist =-(RING_SIZE-b+a);
}
}
else
{
if(a<b)
{
dist = b-a;
}
else
{
dist = RING_SIZE-a+b;
}
}
if(a==b) dist = 0;//Add this if distance between same point must to be 0
return dist;
}
int main()
{
std::cout << distance(7, 2, clockwise) << std::endl;
}
Rama,谢谢你的帮助! – Engo
这些都是非常复杂的答案。这里是一个更简单的:
int distance(int x, int y) {
int d = (y - x) & 7;
return d > 4 ? d - 8 : d;
}
这总是返回范围-3 .. + 4的结果。当环尺寸是2的幂时,模块化算术写起来要简单一些,就像这里的情况一样。
distance(7, 5) = -2
distance(5, 7) = +2
distance(6, 2) = +4
distance(2, 6) = +4
我们使用& 7
,因为它是获得模最简单的方法。另外,您也可以使用% 8
,但你也必须先加入8,以确保输入是不是负数:
int d = (y - x + 8) % 8; // same result
或者,你可以明确地处理负数:
int d = (y - x) % 8;
if (d < 0) {
d += 8;
}
// same result
这是只是一个风格问题。
什么是您的数据模型?像[0,1,2,...,7]这样的矢量? – Dinaiz
是的,你是对的...所以在你的例子中,我想比较0与1,1与2等...... – Engo
告诉我们你有什么,以及你卡在哪里。 –