微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

局部变量和类字段在运行时的行为差异

如何解决局部变量和类字段在运行时的行为差异

我正在尝试编写一个递归方法,用于通过 n查找从 m左上角到右下角旅行的所有可能方式的数量> 网格(不向上移动)。

变量 key 应该保存 mn 的当前值,但是如果我尝试使用类字段,这个变量表现得像是落后了一步什么的。

以下代码将以未处理的异常结束:

添加具有相同密钥的项目。关键:1,1

看起来很像,比如说,当你的初始 mn 分别是 3 和 2 时,(1,2) 的函数会尝试添加它的 value 以“1,1”为键的字典:

class Finder
{
    public Finder()
    {
        memo = new(new List<keyvaluePair<string,ulong>>
        { new keyvaluePair<string,ulong>("1,1",1) });
    }

    private Dictionary<string,ulong> memo;
    private string key;
    private ulong value;

    public ulong Findpaths(int m,int n)
    {
        key = String.Format("{0},{1}",(m < n ? m : n),(m > n ? m : n));

        if (memo.ContainsKey(key))
        {
            return memo[key];
        }

        if (m == 0 || n == 0)
        {
            return 0;
        }

        value = Findpaths(m - 1,n) + Findpaths(m,n - 1);
        memo.Add(key,value);
        return value;
    }
}

当我将 Add 方法中预先计算的 key 更改为最初计算它的相同表达式时,问题就消失了:

memo.Add(String.Format("{0},(m > n ? m : n)),value);

现在,如果我们用局部变量替换 class 字段,一切都会像预期的那样工作:

class Finder
{
    public Finder()
    {
        memo = new(new List<keyvaluePair<string,ulong> memo;
    private ulong value;

    public ulong Findpaths(int m,int n)
    {
        string key;
        key = String.Format("{0},(m > n ? m : n));
        
        if (memo.ContainsKey(key))
        {
            return memo[key];
        }

        if (m == 0 || n == 0)
        {
            return 0;
        }

        value = Findpaths(m - 1,value);

        return value;
    }
}

这种行为差异是否是由于类字段位于堆上而局部变量位于堆栈上的事实造成的?我认为在递归方法中使用类字段比每次方法调用自身时都创建一个本地更实用。

请帮助我更深入地了解这个主题

解决方法

如果您的类中有一个成员变量,则该引用只存在一次。使用递归函数时,所有递归调用都在相同的内存基础上工作,因此类对象中的内容相同。

如果变量在你的函数中是局部的,那么在每个函数调用中它都是一个新的存储和新的变量内容。

当使用你的上层代码时,递归调用本身也会改变键值,然后在“添加”命令中键的内容与递归调用之前不同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。