为什么在此函数中使用模运算符?

时间:2019-09-20 06:23:32

标签: python arrays modulo

我正在努力解决一个挑战:循环阵列。 我希望有人可以帮助我了解我们如何知道在此代码行中使用模运算符吗?

next_index = (current_index + arr[current_index]) % len(arr)

问题描述:我们得到了一个包含正数和负数的数组。假设数组在特定索引处包含数字“ M”。现在,如果“ M”为正,我们将向前移动“ M”指数,如果“ M”为负,则向后移动“ M”指数。您应该假设数组是圆形的,这意味着两件事:

如果在向前移动时到达数组的末尾,则将跳到第一个元素以继续移动。 如果在向后移动时到达数组的开头,则将跳到最后一个元素以继续移动。 编写方法以确定数组是否具有循环。循环中应包含多个元素,并且应遵循一个方向,这意味着循环中不应同时包含前进和后退运动。示例:

Input: [1, 2, -1, 2, 2]
Output: true
Explanation: The array has a cycle among indices: 0 -> 1 -> 3 -> 0

代码

def circular_array_loop_exists(arr):
  for i in range(len(arr)):
    is_forward = arr[i] >= 0  # if we are moving forward or not
    slow, fast = i, i

    # if slow or fast becomes '-1' this means we can't find cycle for this number
    while True:
      # move one step for slow pointer
      slow = find_next_index(arr, is_forward, slow)
      # move one step for fast pointer
      fast = find_next_index(arr, is_forward, fast)
      if (fast != -1):
        # move another step for fast pointer
        fast = find_next_index(arr, is_forward, fast)
      if slow == -1 or fast == -1 or slow == fast:
        break

    if slow != -1 and slow == fast:
      return True

  return False


def find_next_index(arr, is_forward, current_index):
  direction = arr[current_index] >= 0

  if is_forward != direction:
    return -1  # change in direction, return -1

  # ********** This is the line in question ***********
  next_index = (current_index + arr[current_index]) % len(arr)
  # ********** This is the line in question ***********

  # one element cycle, return -1
  if next_index == current_index:
    next_index = -1

  return next_index


def main():
  print(circular_array_loop_exists([1, 2, -1, 2, 2]))
  print(circular_array_loop_exists([2, 2, -1, 2]))
  print(circular_array_loop_exists([2, 1, -1, -2]))


main()

2 个答案:

答案 0 :(得分:2)

模运算符返回除法的余数。您可以了解有关here的更多信息。

在您的上下文中,这意味着它将索引保留在圆形数组中,以避免索引超出范围。

例如,如果您有一个长度为4的数组,但是下一个索引为6,则此代码% len(arr)将6更改为2,因为6%4 =2。因此,它意味着将索引环绕到数组的开头。

如果下一个索引为2,则由于2小于4,因此该操作% len(arr)将产生余数,即2。因此,如果索引在数组的边界内,则索引保持不变。

希望对您有帮助!

答案 1 :(得分:0)

modulo-operator返回给定分区的remainder。假设我们有以下代码:

>>> lst = [i for i in range(5)]
>>> lst
[0, 1, 2, 3, 4]

如果我们尝试在列表之外调用index,则会收到错误消息:

>>> lst[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

由于modulo-operator返回了remainder,尽管我们可以执行以下操作:

>>> lst[5 % len(lst)]
0

这是因为remainder中的5 / 50。如果我们改为尝试6,则会得到以下结果:

>>> lst[6 % len(lst)]
1

再一次,是因为remainder6 / 5时的1