我想借助附圖中描述的系統計算數字之間的距離。如何計算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
告訴我們你有什麼,以及你卡在哪裏。 –