エントリのデータベーステーブルに基づいてディレクトリのフルパスを見つける関数を書いています。各レコードには、キー、ディレクトリ名、および親ディレクトリのキーが含まれています(使い慣れている場合は、MSIのディレクトリテーブルです)。私は反復的な解決策を持っていましたが、それは少し厄介に見え始めました。エレガントな末尾再帰ソリューションを作成できると思いましたが、もうわかりません。
私のコードを紹介してから、私が直面している問題について説明します。
Dictionary<string, string> m_directoryKeyToFullPathDictionary = new Dictionary<string, string>();
...
private string ExpandDirectoryKey(Database database, string directoryKey)
{
// check for terminating condition
string fullPath;
if (m_directoryKeyToFullPathDictionary.TryGetValue(directoryKey, out fullPath))
{
return fullPath;
}
// inductive step
Record record = ExecuteQuery(database, "SELECT DefaultDir, Directory_Parent FROM Directory where Directory.Directory='{0}'", directoryKey);
// null check
string directoryName = record.GetString("DefaultDir");
string parentDirectoryKey = record.GetString("Directory_Parent");
return Path.Combine(ExpandDirectoryKey(database, parentDirectoryKey), directoryName);
}
これは、問題が発生したことに気付いたときのコードの外観です(マイナーな検証/マッサージが削除されています)。可能な限りメモ化を使用して短絡させたいのですが、再帰ExpandDirectoryKey
呼び出しの出力を格納するために辞書への関数呼び出しを行う必要があります。そこにも電話があることに気づきましたが、それは。Path.Combine
で回避できると思います... + Path.DirectorySeparatorChar + ...
。
上記の関数の最後で次のように呼び出すことができるように、ディレクトリをメモ化して値を返すヘルパーメソッドを使用することを考えました。
return MemoizeHelper(
m_directoryKeyToFullPathDictionary,
Path.Combine(ExpandDirectoryKey(database, parentDirectoryKey)),
directoryName);
しかし、それは不正行為であり、末尾再帰として最適化されないように感じます。
何か案は?まったく異なる戦略を使用する必要がありますか?これは非常に効率的なアルゴリズムである必要はまったくありません。私は本当に興味があります。私は.NET4.0を使用しています。
ありがとう!
PS私の終了条件について疑問に思っている場合でも、心配しないでください。辞書にルートディレクトリを事前にシードします。