【问题标题】:How to make a static local variable in golang如何在golang中制作静态局部变量
【发布时间】:2021-08-10 03:15:36
【问题描述】:
/*
Description: Write a function canSum(targetSum, numbers) that takes in a
targetSum and an array of numbers as arguments.

The function should return a boolean indicating whether or not it is possible  
to generate the targetSum using numbers from the array

You may use an element of the slice as many times as needed.
Assume that all input numbers are non-negative.

*/
package main

import "fmt"

func canSum(targetSum int, numbers ...int) bool {
    if targetSum == 0 {
        return true
    }
    if targetSum < 0 {
        return false
    }
    for index := 0; index < len(numbers); index++ {
        if canSum(targetSum-numbers[index], numbers...) == true {
            return true
        }
    }
    return false
}

//var memo = map[int]bool{} //Getting wrong values due to shared function scope from package scope
func memo_canSum(targetSum int, numbers ...int) bool {
    memo := map[int]bool{} //Defeats dp func since we continue to reinitialize during recursive calls
    if _, exists := memo[targetSum]; exists {
        return memo[targetSum]
    }

    if targetSum == 0 {
        return true
    }
    if targetSum < 0 {
        return false
    }
    for index := 0; index < len(numbers); index++ {
        if memo_canSum(targetSum-numbers[index], numbers...) == true {
            memo[targetSum] = true
            return memo[targetSum]
        }
    }
    memo[targetSum] = false
    return false
}

func main() {

    //Non-Dp Solution
    fmt.Println(canSum(21, 2, 4, 8))
    fmt.Println(canSum(80, 2, 4, 8))
    fmt.Println(canSum(300, 7, 14))

    //Dp Solution
    fmt.Println(memo_canSum(21, 2, 4, 8))
    fmt.Println(memo_canSum(80, 2, 4, 8))
    fmt.Println(memo_canSum(300, 7, 14))
}

所以我在使用 golang 编程时遇到了一个问题,如果我在函数之外声明我的记忆地图,那么所有函数调用都共享同一个地图,这会导致结果出错。 如果我在函数内声明地图,那么每个递归调用都会重新初始化地图。有什么办法可以使地图成为静态局部变量?

【问题讨论】:

  • 没有。进行递归调用时,只需将其作为参数传递即可。
  • 是的,我很害怕,我想我必须用 C++ 重写问题,因为我必须符合问题描述。
  • 我不明白为什么......在你的情况下,你可以只使用一个包映射并在memo_canSum的开头初始化它。更有弹性的解决方案是让memo_canSum 调用一个函数,该函数将映射作为参数,执行实际工作和递归,从而保持memo_canSum 的签名完整。

标签: go recursion dynamic-programming memoization static-variables


【解决方案1】:

map parameter 编写一个不同的函数并在其中进行递归。最初在 memo_canSum 函数中调用该函数并声明新地图。

//var memo = map[int]bool{} //Getting wrong values due to shared function scope from package scope
func memo_canSum(targetSum int, numbers ... int) bool {
    memo := map[int]bool{} //Defeats dp func since we continue to reinitialize during recursive calls
    return momoWithMap(memo, targetSum, numbers...)
}

func momoWithMap(memo map[int]bool, targetSum int, numbers ... int) bool{
    if _, exists:=memo[targetSum]; exists{
        return memo[targetSum]
    }

    if targetSum == 0 {
        return true
    }
    if targetSum < 0{
        return false
    }
    for index:= 0; index < len(numbers); index++{
        if momoWithMap(memo, targetSum - numbers[index], numbers...) == true {
            memo[targetSum] = true
            return true
        }
    }
    memo[targetSum] = false
    return false
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 2011-01-05
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    相关资源
    最近更新 更多