Как вычислить расстояние между числами в с ++?
6 ответов
Если вы делаете это простым способом (с учетом всех возможностей), это может выглядеть следующим образом
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);
}
Альтернативный, более элегантный подход состоит в том, чтобы всегда вычислять положительное расстояние по часовой стрелке и переворачивать его на отрицательное расстояние по часовой стрелке, если оно больше 4
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;
}
Это действительно сложные ответы. Вот более простой:
int distance(int x, int y) {
int d = (y - x) & 7;
return d > 4 ? d - 8 : d;
}
Это всегда возвращает результат в диапазоне -3..+4. Модульную арифметику немного проще написать, когда размер кольца является степенью двойки, как здесь.
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
Это просто вопрос стиля.
Следующий код подготовлен для удовлетворения всех ваших потребностей, например, я предполагаю, что если направление по часовой стрелке, расстояние должно быть отрицательным.
#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;
}
Для простоты вы можете найти элемент из std::find и получить расстояние от начала от std::distance
например, как вы упомянули данные, сохраненные в int vector
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édi Ghédiri, вы не будете считать против часовой стрелки оба раза. Я предполагаю, что вы считаете кратчайший путь к числу. (Я использовал математическое
min()
функция)Вы предпочитаете положительное значение отрицательному значению (комментарий Харпера). Если вы предпочитаете отрицательное значение, переключите последние два
if
заявления.
Может быть более краткий метод, но это (надеюсь) работает. Пожалуйста, прокомментируйте, если это не так. Надеюсь, что это полезно!
Изменить: это psuedocode. Это должно быть легко написать на С ++. Использовать abs()
функция в <stdlib.h>
Забудь о list
а также length(list)
, использование int
типы для переменных, и все остальное должно работать.
Я думаю, что это должно работать
int func(a,b)
{
dist=(b-a);
if(dist<0)
dist +=8;
return dist;
}
в случае, если вы действительно застряли