如何实现这种无突变的算法

时间:2015-12-02 17:10:47

标签: javascript algorithm

我正在尝试使用不变性,高阶函数和/或递归(无循环或变异)在函数式语言中实现以下算法。

算法迭代一个列表,对于每对相邻元素,如果左边大于右边,则交换它们。

但是,如果两个相邻元素之间的差异小于某个数字(比如10),则应使用这些作为参数调用函数(notify

关于如何重写它的任何提示?

for (i = 1, i < queue.legth, i++) {
  left = queue[i-1]
  right = queue[i]

  if (abs(left - right) < 10) {
    notify(left, right)
  } else if (left > right) {
    queue[i-1] = right
    queue[i] = left
  }
}

更新

是的,不是改变列表,而是应该返回一个新列表

1 个答案:

答案 0 :(得分:2)

JavaScript是一种可怕的语言。但这是一个想法。

首先实现链接列表。您的API可能包含以下命令:

var empty_list = create_empty_list()
var larger_list = list.prepend(thing)
var is_empty = list.is_empty()
var first_element = list.head()
var tail = list.tail()
var reversed_list = list.reversed()

在内部,链表只是一个带头的对象,另一个是指向尾的对象。因此,在列表前面只是意味着创建一个新节点,其新值指向旧节点。 (即不是变异!)所以你有了访问者。然后reversed是一个简单的递归函数。 (您需要一个帮助函数list._reversed(tail),然后list.reversed()只是list._reversed(create_empty_list())。帮助函数返回tail表示空列表,否则返回this.tail._reversed(tail.prepend(this.head))。)

使用链接列表,您可以遍历队列,构建重新排列的列表并在您想要的位置调用notify。当你完成对队列的迭代时,你会有一个完全向后的链表。但是,您可以调用reversed以正确的顺序获取队列。