【发布时间】:2016-11-08 23:28:25
【问题描述】:
我有一个编码树的Dictionary<T, IEnumerable<T>>:
键代表树的所有节点,值是相应节点的子节点。
如果一个节点没有子节点,那么它的值就是一个空的可枚举。
例如以下treeMap 与T = int 的映射就是这样一个对树进行编码的映射:
treeMap[1] = { 2, 3, 4 }
treeMap[2] = { 5, 6 }
treeMap[3] = { 7 }
treeMap[4] = { }
treeMap[5] = { }
treeMap[6] = { }
treeMap[7] = { 8 }
treeMap[8] = { }
我想编写一个方法UseFunctionOnTree(T node, Dictionary<T, IEnumerable<T>> treeMap, Function F),将F 应用于给定节点,从旧的F 和node 获取一个新函数newF,并将newF 应用于所有子节点。
据我所知:
public class MapHelper<T>
{
public delegate Function Function (T element);
public static void UseFunctionOnTree(T node,
Dictionary<T, IEnumerable<T>> treeMap, Function F)
{
Function newF = F(node);
foreach (T child in treeMap[node])
UseFunctionOnTree (child, treeMap, newF);
}
}
现在我的问题是我不知道如何定义这样的Function。
我可以这样定义:
public Function Useless(T element)
{
DoSthWith(element);
return Useless;
}
但是我不知道如何定义一个返回自身以外的东西的函数!
我的一个用例如下:
我有一棵 MyObject 类型的树,其中 MyObject 可能如下所示:
public class MyObject
{
public int index;
}
我取了一些int-valued 偏移量,比如说firstOffset = 3。我希望Function 将offset 添加到node(即添加到其index)。然后我想给node的所有孩子添加一个偏移量,但是这次的偏移量应该是nextOffset = firstOffset + node.index。
这是我想要的伪代码:
public Function AddOffset(T element)
{
int firstOffset;
// somehow make firstOffset = 3
int newOffset = firstOffset + element.index;
element.index = newOffset;
return AddOffset // but this time with the new offset
}
我该怎么做?我觉得它可能可以通过一些 lambda 语句来解决......
我需要更多参数吗?从直觉的角度来看,我没有。 例如。我们有
node1 与 node1.index = 1 和
node2 与 node2.index = 100。
我们将F 指定为
“将 3 添加到参数的索引并将该数字存储为 n。返回一个类似的函数,但将 n 添加到其参数的索引。”
从中我们得到F(node1) 将更改node1.index 为3+1=4 并将4 添加到其参数的索引,因此(F(node1))(node2) 将更改node2.index 到4+100=104 并将104 添加到它是参数的索引。而((F(node1))(node2))(node1) 会将node1.index 更改为104+4=108 并将108 添加到其参数的索引中,依此类推。
我还想指出,我并不总是需要/更改一个int 参数。可能是我需要几个参数,它们的类型也可能因我要解决的具体问题而异。因此,如果我不必提前决定我需要多少(以及什么类型)参数,那就太好了。它应该全部包含在Function 本身中。
感谢任何提示!
【问题讨论】:
-
等等,你的意思是T类型的函数,它需要一个T类型的函数,它返回一个T类型的函数,它需要一个T类型的函数,并返回一个T类型的函数,它返回一个函数需要一个返回 T 类型函数的函数?反之亦然?
-
请注意,您将
index定义为double,稍后您将像int一样使用它。 -
另请注意,您不能使用此修改树结构!当您将树节点存储在映射中时,您无法通过更改某些索引值来更改树结构(节点和子节点),因为
Dictionary确实假定包含的键的哈希码保持不变! -
@ventiseis 我将双精度更正为 int。对于哈希码,我们假设它是由其他一些永远不会改变的字段定义的。不过感谢提示,我忽略了这个问题。
标签: c# recursion functional-programming delegates