我希望找到一种有效的方法来对具有以下特征的 TreeMap 中的项目进行分组:
关于 TreeMap ,它有多个层,如果水平绘制:
(0,0)--(1,0)--(2,0)
\ \-(1,1)--(2,1)
\--(1,2)--/
- 对于由类 Node 建模的节点 (x,y),x 是它的“级别”,而 y 是它的“索引”。对于任何边,我们只允许该边的两个节点的顺序索引,因此 (1,2)-(3,2) 是禁止的。
- 允许多个根:(0,0) (0,1) ...等
关于“分组项目”: 因为在树的数据源中有这样的节点:
(3,5)--(4,10)--(5,5)
\ \-(4,11)-/ /
\ .... /
\--(4,80)--/
我希望将上述(4,10~80)这样的节点归为一个节点,这些节点具有相同的特征
- 只有 1 个它们共享的父节点
- 只有 1 个他们共享的子节点
- 还需要解决他们只有一个共同的 parent (或一个共同的 child )但根本没有 child (或 parent )的情况。
使用一个特殊的类 CompoundNode,它是 Node 的一个子类。
这是 Node 的骨架类:
public class Node
{
public Node(string id)
{
Id = id;
}
public string Id { get; set; }
private readonly List<Node> children = new List<Node>();
public List<Node> Children { get { return children; } }
private readonly List<Node> parents = new List<Node>();
public List<Node> Parents { get { return parents; } }
protected bool Equals(Node other)
{
....
}
public override bool Equals(object obj)
{
....
}
public override int GetHashCode()
{
return (Id != null ? Id.GetHashCode() : 0);
}
public override string ToString()
{
....
}
}
谢谢!
编辑:
这是我所做的解决方案(提取关系而不修改树),没有解决零父或零子的情况:
var relationships = new List<Tuple<string, string, string>>();
foreach (var middle in nodes)
{
if (middle.Children.Count == 1 && middle.Parents.Count == 1)
{
var child = middle.Children[0];
var parent = middle.Parents[0];
relationships.Add(new Tuple<string, string, string>(parent.Id, middle.Id, child.Id));
}
}
var groups = relationships.GroupBy(t => new { t.Item1, t.Item3 }).Where(a => a.Count() > 1);
var toGroupedRelations = groups.Cast<IEnumerable<Tuple<string, string, string>>>().ToList();
最佳答案
好的 - 这是第一次尝试。无论如何应该给你一些好的指示:
var nodes = new List<Node>();
// !! populate your nodes list with all your real nodes first!
// filter to nodes with at most 1 parent and 1 child
// group by a tuple containing the parent (if it exists) and the child (if it exists)
var grouped = nodes.Where(i => i.Children.Count <= 1 && i.Parents.Count <= 1)
.GroupBy(i =>
new Tuple<Node, Node>(i.Parents.Count == 0 ? null : i.Parents[0],
i.Children.Count == 0 ? null : i.Children[0]));
// go through your groups - each one should be a cluster of nodes to be merged
foreach (var group in grouped)
{
// get the first node in the group (which one is arbitrary if we're merging anyway)
var node = group.First();
// if this group has a parent
if (node.Parents.Count == 1)
{
// change the parent to only have one child - this one!
node.Parents[0].Children.Clear();
node.Parents[0].Children.Add(node);
}
// if this group has a child
if (node.Children.Count == 1)
{
// change the child to only have one parent - this one!
node.Children[0].Parents.Clear();
node.Children[0].Parents.Add(node);
}
}
关于c# - 在 C# 中对共享相同父项和子项的项进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19993526/