动态编程斐波那契Swift

时间:2018-10-24 04:58:34

标签: swift algorithm

我正在尝试将以下实现隐瞒给Swift并遇到困难:

var mem = [];
var fibRecursiveMem = function (n) {
    if (mem[n]) return mem[n];
    if (n<=2) mem[n] = 1;
    else {
        mem[n] = fibRecursiveMem(n-1) + fibRecursiveMem(n-2);
    }
    return mem[n];
} 

来自:https://dev.to/rattanakchea/dynamic-programming-in-plain-english-using-fibonacci-as-an-example-37m1

我在Swift中的实现

var mem = [Int]()
func fib (_ num: Int) -> Int {
    if (mem.count - 1 > num) {
        return mem[num]
    }
    if (num<=2) {mem[num] = 1}
    else {
        mem[num] = fib(num-1) + fib(num-2)
    }
    return mem[num]
}

产生索引超出范围的错误。

现在,我想遵循原始算法的一般逻辑。我在翻译中做错什么了?

3 个答案:

答案 0 :(得分:5)

在这种情况下,最好使用字典来实现内存:

var mem = [Int: Int]()
func fib (_ num: Int) -> Int {
    if let cached = mem[num] {
        return cached
    }

    let result: Int

    if (num <= 2) {
        result = 1
    }
    else {
        result = fib(num - 1) + fib(num - 2)
    }

    mem[num] = result
    return result
}

在javascript中,数组和字典之间的差异很小。即使将mem声明为数组,它实际上也被用作字典。

要使用数组,我们必须确保始终正确append

var mem = [1, 1, 1] // prefill initial values for 0, 1, 2
func fib (_ num: Int) -> Int {
    if num < mem.count {
        return mem[num]
    }

    let result = fib(num - 1) + fib(num - 2)
    // the recursion has already appended all previous values
    mem.append(result)

    return result
}

答案 1 :(得分:1)

一种实现方法是将数组声明为包含一些元素,并将它们初始化为已知的无效值,例如-1。这将创建数组元素,并告诉您尚未向其写入值。知道这一点之后,您就可以确定是否已经存在可以查询并返回的值,或者是否需要计算该条目的值。看起来像这样:

let kUnitialized = -1
var mem = Array(repeating: kUnitialized, count: 100)

func fib (_ num: Int) -> Int {
    if (mem[num] != kUnitialized) {
        return mem[num]
    }
    if (num <= 2) {
        mem[num] = 1
    } else {
        mem[num] = fib(num - 2) + fib(num - 1)
    }
    return mem[num]
}

请注意,在这种情况下,永远不能使用大于数组中包含的元素数量的参数调用fib。 (在示例中为100。)

答案 2 :(得分:0)

我尝试仅使用array中的integers

获得正确的输出:

var mem = [Int]()
func fib (_ num: Int) -> Int {
    if (mem.count > num) {
        return mem[num - 1]
    }

    switch num {
    case 2:
        if mem.count == 0 {
            for _ in 0..<2 {
                mem.append(1)
            }
        }
        else if mem.count == 1 {
            mem.append(1)
        }
    case 1:
        if mem.count == 0 {
            mem.append(1)
        }
    default:
        mem.append(fib(num-1) + fib(num-2))
    }

    print(mem)

    return mem[num - 1 ]
}