2016-11-25 120 views
0

我想借助附图中描述的系统计算数字之间的距离。如何计算C++中的数字之间的距离?

例如:7和5之间的距离为-2,7和1之间的距离是2等...

任何想法如何在C为此++?首选的方向是逆时针... 我正在使用(int)向量。

enter image description here

+0

什么是您的数据模型?像[0,1,2,...,7]这样的矢量? – Dinaiz

+0

是的,你是对的...所以在你的例子中,我想比较0与1,1与2等...... – Engo

+0

告诉我们你有什么,以及你卡在哪里。 –

回答

2

如果你这样做的简单的方法(通过考虑所有可能性),它可能如下

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; 
} 
+0

非常感谢您的精彩回答!它真的帮了我很多! – Engo

+0

我有点不确定在这里应该实现'unsigned'的转换。给定范围内的输入似乎是严格不必要的。 –

+0

@Dietrich Epp:通过使用'unsigned'类型,我们向编译器传递了一些关键信息。切换到'unsigned'类型允许编译器为'(b + 8 - a)%8'表达式生成更高效的代码,因为只要类型是'unsigned',这个表达式的语义就相当于你的' (b - a)&7'。举一个例子,GCC只要使用'unsigned'类型就会生成相同的代码。划分下的“签名”类型的语义是非常不同的,这导致更复杂和更低效的机器码。 – AnT

0

认为这应该

int func(a,b) 
{ 
    dist=(b-a); 
    if(dist<0) 
     dist +=8; 
    return dist; 

} 

在你真的坚持

+0

不适用于'func(0,4)',返回12,而不是4. –

+0

@Timothy Higinbottom:对于'func(0,4)',它实际上工作正常并返回'4'。但它不符合其他要求。 – AnT

+0

@安:真的,对不起,我的错误 –

1

为了简单起见情况下,你可以从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() 

所以希望这会给距离图像...

1

我敢肯定,这个工程:

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()是数学绝对值函数。

我在这里做一些假设。

  1. 正如@HédiGhédiri指出的那样,你不是在逆时针计数。我假设你算数的最短路径。 (我用数学min()函数)

  2. 你更喜欢正值超过负值(@哈珀的评论)。如果您偏好负值,请切换最后两个if语句。

可能有一个更简洁的方法,但这(希望)的作品。请评论,如果它是错误的。希望这有帮助!

编辑:这是psuedocode。用C++编写应该很容易。使用<stdlib.h>中的abs()函数忘记listlength(list)。对变量使用int类型,其他所有内容都应该有效。

+0

谢谢你的伪代码! – Engo

1

的以下代码准备满足您的所有需求,例如我假设,如果方向为顺时针,则距离为负。

#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; 
} 
+0

Rama,谢谢你的帮助! – Engo

2

这些都是非常复杂的答案。这里是一个更简单的:

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

太棒了,我真的很喜欢这个聪明的答案! – Engo

+0

据我所见,这段代码覆盖了所有要求,并且非常短,很好:) – Engo

+0

@Engo:代码确实覆盖了所有要求,但不必要地依赖于底层平台使用的二进制表示。对于负数,“&7”与“%8”的等价关系不受语言保证,即使它可以在绝大多数平台上工作。 – AnT

相关问题