gpt4 book ai didi

c# - 来自邻接列表的 JSON?

转载 作者:太空宇宙 更新时间:2023-11-03 22:01:53 24 4
gpt4 key购买 nike

我有一个这样的邻接表:

A   -  A1
A - A2
A - A3
A3 - A31
A31 - A311
A31 - A312

我正在尝试获得以下输出:

{
"name": "A",
"children": [{
"name": "A1"
}, {
"name": "A2"
}, {
"name": "A3",
"children": [{
"name": "A31",
"children": [{
"name": "A311"
}, {
"name": "A312"
}]
}]
}]
};

我有一个包含 10 万个链接的适度大图。这样做的好方法是什么?我认为有一种非常优雅的递归方法可以执行此操作,但我不确定如何直接创建 JSON 字符串。

最佳答案

类似的东西应该可以工作:

static void Main(string[] args)
{
var adjList = new List<Link>
{
new Link("A","A1"),
new Link("A","A2"),
new Link("A","A3"),
new Link("A3","A31"),
new Link("A31","A311"),
new Link("A31","A312"),
};

var rootsAndChildren = adjList.GroupBy(x => x.From)
.ToDictionary(x => x.Key, x => x.Select(y => y.To).ToList());
var roots = rootsAndChildren.Keys
.Except(rootsAndChildren.SelectMany(x => x.Value));

using (var wr = new StreamWriter("C:\\myjson.json"))
{
wr.WriteLine("{");
foreach (var root in roots)
AppendSubNodes(wr, root, rootsAndChildren, 1);
wr.WriteLine("};");
}
}

static void AppendSubNodes(TextWriter wr, string root,
Dictionary<string, List<string>> rootsAndChildren, int level)
{
string indent = string.Concat(Enumerable.Repeat(" ", level * 4));
wr.Write(indent + "\"name\" : \"" + root + "\"");
List<string> children;
if (rootsAndChildren.TryGetValue(root, out children))
{
wr.WriteLine(",");
wr.WriteLine(indent + "\"children\" : [{");
for (int i = 0; i < children.Count; i++)
{
if (i > 0)
wr.WriteLine(indent + "}, {");
AppendSubNodes(wr, children[i], rootsAndChildren, level + 1);
}
wr.WriteLine(indent + "}]");
}
else
{
wr.WriteLine();
}
}

Link 是以下类:

class Link
{
public string From { get; private set; }
public string To { get; private set; }
public Link(string from, string to)
{
this.From = from;
this.To = to;
}
}

前面代码的结果:

{
"name" : "A",
"children" : [{
"name" : "A1"
}, {
"name" : "A2"
}, {
"name" : "A3",
"children" : [{
"name" : "A31",
"children" : [{
"name" : "A311"
}, {
"name" : "A312"
}]
}]
}]
};

编辑:

如果你想检查图形循环的存在,你可以执行以下操作(就在 rootsAndChildren 字典创建之后)

var allNodes = rootsAndChildren.Keys.Concat(rootsAndChildren.SelectMany(x => x.Value)).Distinct();
Func<string, IEnumerable<string>> getSuccessors =
(x) => rootsAndChildren.ContainsKey(x) ? rootsAndChildren[x] : Enumerable.Empty<string>();

var hasCycles = new Tarjan<string>().HasCycle(allNodes, getSuccessors);

Tarjan 是以下类:

// Please note that Tarjan does not detect a cycle due to a node 
// pointing to itself. It's pretty trivial to account for that though...
public class Tarjan<T>
{
private class Node
{
public T Value { get; private set; }
public int Index { get; set; }
public int LowLink { get; set; }
public Node(T value)
{
this.Value = value;
this.Index = -1;
this.LowLink = -1;
}
}
private Func<T, IEnumerable<T>> getSuccessors;
private Dictionary<T, Node> nodeMaps;
private int index = 0;
private Stack<Node> stack;
private List<List<Node>> SCC;
public bool HasCycle(IEnumerable<T> nodes, Func<T, IEnumerable<T>> getSuccessors)
{
return ExecuteTarjan(nodes, getSuccessors).Any(x => x.Count > 1);
}
private List<List<Node>> ExecuteTarjan(IEnumerable<T> nodes, Func<T, IEnumerable<T>> getSuccessors)
{
this.nodeMaps = nodes.ToDictionary(x => x, x => new Node(x));
this.getSuccessors = getSuccessors;
SCC = new List<List<Node>>();
stack = new Stack<Node>();
index = 0;
foreach (var node in this.nodeMaps.Values)
{
if (node.Index == -1)
TarjanImpl(node);
}
return SCC;
}
private IEnumerable<Node> GetSuccessors(Node v)
{
return this.getSuccessors(v.Value).Select(x => this.nodeMaps[x]);
}
private List<List<Node>> TarjanImpl(Node v)
{
v.Index = index;
v.LowLink = index;
index++;
stack.Push(v);
foreach (var n in GetSuccessors(v))
{
if (n.Index == -1)
{
TarjanImpl(n);
v.LowLink = Math.Min(v.LowLink, n.LowLink);
}
else if (stack.Contains(n))
{
v.LowLink = Math.Min(v.LowLink, n.Index);
}
}
if (v.LowLink == v.Index)
{
Node n;
List<Node> component = new List<Node>();
do
{
n = stack.Pop();
component.Add(n);
} while (n != v);
SCC.Add(component);
}
return SCC;
}
}

关于c# - 来自邻接列表的 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9800949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com