2016-11-25 72 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

相關問題