English 中文(简体)
两个参数记忆化
原标题:
  • 时间:2009-03-11 06:08:59
  •  标签:

在C#中,我如何记忆化带有两个参数的函数?

我需要先进行记忆化前的曲奇吗?

韦斯·戴尔编写了我通常使用的Memoization代码,但现在我需要两个参数。

最佳回答

你只需要创建一个过载版本的Memoize方法,具有三个泛型类型,并使用两个参数和函数,同时仍然返回一个无参数的函数:

public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2)
{
  R value = default(R);
  bool hasValue = false;
  return () =>
    {
      if (!hasValue)
      {
        hasValue = true;
        value = f(a1,a2);
      }
      return value;
    };
}

Edit:
Alternatively, you need to make a custom IEqualityComparer for a KeyValuePair that contains the two arguments, for the Memoize method to be able to return a function with two parameters:

public static Func<A1,A2,R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, IEqualityComparer<KeyValuePair<A1,A2>> comparer)
{
   var map = new Dictionary<KeyValuePair<A1,A2>,R>(comparer);
   return (a1,a2) =>
      {
         R value;
         KeyValuePair<A1,A2> key = new KeyValuePair<A1,A2>(a1,a2);
         if (map.TryGetValue(key, out value)) {
            return value;
         }
         value = f(a1,a2);
         map.Add(key, value);
         return value;
      };
}
问题回答

Wes在另一篇帖子中介绍了Memoize的两个(或更多)参数版本。它不需要自定义比较器。

使用新版本的.NET,您可以通过使用元组来简化接受的解决方案的代码。

    public static Func<TParam1, TParam2, TReturn> Memoize<TParam1, TParam2, TReturn>(Func<TParam1, TParam2, TReturn> func)
    {
        var map = new Dictionary<Tuple<TParam1, TParam2>, TReturn>();
        return (param1, param2) =>
        {
            var key = Tuple.Create(param1, param2);
            TReturn result;
            if (!map.TryGetValue(key, out result))
            {
                result = func(param1, param2);
                map.Add(key, result);
            }
            return result;
        };
    }

你应该能够记忆化一个键值对。这个两个参数的函数调用一个单个参数的函数进行记忆化。

我在 C# 中也对记忆化进行了一些工作。我的结果类似,但使用从输入对象哈希码串联而成的字典键。该模式可以扩展到 Func<> 允许的任意数量的输入。

更多信息请查看此处:http://bit.ly/t6iNJP





相关问题
热门标签