我正在编写一个函数,该函数根据数据库条目表查找目录的完整路径。每条记录都包含一个键、目录的名称和父目录的键(如果您熟悉,它就是 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);
但我觉得这是作弊,不会被优化为尾递归。
有任何想法吗?我应该使用完全不同的策略吗?这根本不需要是一个超级高效的算法,我只是很好奇。我正在使用.NET 4.0,顺便说一句。
谢谢!
PS如果你想知道我的终止条件,别担心。我用根目录预播字典。