循环数字序列中两个数字之间的距离

时间:2016-08-05 20:16:38

标签: javascript

我想找到循环序列中两个数字之间的最短距离,例如0到6:

library(data.table); library(stringr)
lapply(tstrsplit(my_list, "\\|"), function(s) t(str_split_fixed(s, "--", 2)))

#[[1]]
#     [,1]     [,2]     [,3]    
#[1,] "Jan-01" "Jan-01" "Jul-06"
#[2,] "Dec-31" "Jun-30" "Dec-31"

#[[2]]
#     [,1]    [,2]    [,3]   
#[1,] "00:00" "12:00" "09:00"
#[2,] "24:00" "18:00" "19:00"

还需要知道哪种“方式”更短(向左或向右)。

所以,如果我的两个数字是0和6,那么通过向后计数(向左),最短距离是1。

以下功能有效,但仅当... 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 ... 大于next时才有效。

crt

我无法弄清楚如何让它在两个方面都有效。例如,如果我使用var MAX_NUMBER = 6; // 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 function shorterDirection(crt, next) { var toRight = next - crt; var toLeft = MAX_NUMBER - (next - crt - 1); return toLeft < toRight ? 'left' : 'right'; } console.log(shorterDirection(0, 6)); ,我希望函数返回shorterDirection(4, 3)

2 个答案:

答案 0 :(得分:1)

你可以用这个:

function shorterDirection(crt, next) {
  var toRight = (next + MAX_NUMBER+1 - crt) % (MAX_NUMBER+1);
  return toRight > (MAX_NUMBER+1) / 2 ? 'left' : 'right';
}

请注意,可以有联系。在这种情况下,上述内容将返回left,即使right同样出色。

正如你所看到的,那里有很多MAX_NUMBER+1。如果你有一个常数NUMBER_COUNT会比你现在拥有的MAX_NUMBER更大,那就更合适了。

如何运作

首先写下这个:

var toRight = next - crt;

但当 next 小于 crt 时,这会出现“错误” - 您会得到一个负数。要解决此问题,您需要添加MAX_NUMBER+1

var toRight = next + NUMBER+1 - crt;

...但是现在当 next 大于 crt 时,你会得到一个太大的数字。您可以通过减少所需的NUMBER+1来解决,以便在 0 ... MAX_NUMBER 范围内。这就是modulo(%)运算符的作用。所以你得到:

var toRight = (next + MAX_NUMBER+1 - crt) % (MAX_NUMBER+1);

一旦你得到了这个结果,你可以推断如果需要超过一半的数字向右移动,你最好向左移动(这将少于数字的一半)。这编码为:

return toRight > (MAX_NUMBER+1) / 2 ? 'left' : 'right';

答案 1 :(得分:1)

你的记法错了。您在Z/7Z中使用modular arithmetic

参数应为7,而不是6

我会在一个方向和另一个方向上得到距离并进行比较:

var modulus = 7; /* Z/7Z */
function shorterDirection(crt, next) {
  var toRight = (next - crt + modulus) % modulus;
  var toLeft = (crt - next + modulus) % modulus;
  return toLeft < toRight ? 'left' : 'right';
}

上面的代码假设两个参数都属于{0, ..., modulus-1}。如果您想允许更宽的范围,例如{modulus+1, ..., modulus-1},计算距离的正确方法是

((next - crt) % modulus + modulus) % modulus;
((crt - next) % modulus + modulus) % modulus;