C# では、2 つの引数を持つ関数をメモ化するにはどうすればよいですか?
メモ化の前にカレーをしなければなりませんか?
Wes Dyer は、私が通常使用するメモ化コードを作成しましたが、現在は 2 つの引数が必要です
C# では、2 つの引数を持つ関数をメモ化するにはどうすればよいですか?
メモ化の前にカレーをしなければなりませんか?
Wes Dyer は、私が通常使用するメモ化コードを作成しましたが、現在は 2 つの引数が必要です
Wes は別の投稿で、2 つ (またはそれ以上) 引数のバージョンの Memoize を提供しています。カスタム比較は必要ありません。
3 つのジェネリック型を持ち、2 つのパラメーターと 2 つの引数を持つ関数を受け取る、オーバーロードされたバージョンの 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;
};
}
編集:
または、Memoize メソッドが 2 つのパラメーターを持つ関数を返すことができるように、2 つの引数を含む KeyValuePair のカスタム IEqualityComparer を作成する必要があります。
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;
};
}
.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;
};
}
ペアをメモできるはずです。two arg 関数は、メモ化した単一の arg 関数を呼び出します。
また、C# でのメモ化に関する作業も行いました。私の結果は似ていますが、入力オブジェクト ハッシュ コードの連結から派生した辞書キーを使用します。パターンは Func<> が許す限り多くの入力に拡張できます。
詳細はこちら: http://bit.ly/t6iNJP