C# 如何根据依赖项在数组中重新排列项?并检测任何循环依赖关系
给定类型:C# 如何根据依赖项在数组中重新排列项?并检测任何循环依赖关系,c#,arrays,sorting,dependencies,cyclic,C#,Arrays,Sorting,Dependencies,Cyclic,给定类型: class Field{ public string Name{get;set;} public string[] DependsOn{get;set;} } 假设我有一个字段项的数组: List<Field> fields = new List<Field>(); fields.Add(new Field() { Name = "FirstName" }); fields.Add(new Field() { Name = "FullName
class Field{
public string Name{get;set;}
public string[] DependsOn{get;set;}
}
假设我有一个字段项的数组:
List<Field> fields = new List<Field>();
fields.Add(new Field() { Name = "FirstName" });
fields.Add(new Field() { Name = "FullName",
DependsOn = new[] {"FirstName","LastName"}});
fields.Add(new Field() { Name = "Age",
DependsOn = new[] { "DateOfBirth" } });
fields.Add(new Field() { Name = "LastName" });
fields.Add(new Field() { Name = "DateOfBirth" });
列表字段=新列表();
添加(新字段(){Name=“FirstName”});
添加(新字段(){Name=“FullName”,
DependsOn=new[]{“FirstName”,“LastName”});
添加(新字段(){Name=“Age”,
DependsOn=new[]{“出生日期”});
添加(新字段(){Name=“LastName”});
添加(新字段(){Name=“DateOfBirth”});
因此,很明显,我们按照以下顺序购买产品:
名字
全名
年龄
姓氏
出生日期
我的第一个问题:
重新排列列表/数组中的项目的最佳方式是什么,以便将相关列(全名和年龄)放在它们所依赖的列之后,例如:
名字
姓氏
全名
出生日期
年龄
所以像Age这样的字段总是在它所依赖的出生日期之后
我的第二个问题:
是否有方法检测循环依赖关系?i、 e.何时
Field1
取决于Field2
和
Field2
取决于Field3
和
Field3
取决于Field1
这样我们就不会陷入圈套。e、 大学毕业后,你需要2年的工作经验才能找到工作。但是要获得工作经验,你首先需要得到这份工作。听起来你需要按拓扑顺序对这些项目进行排序。网络上有很多页面,也许维基百科是一个很好的起点:
听起来您需要按拓扑顺序对这些项目进行排序。网络上有很多页面,也许维基百科是一个很好的起点:
谢谢你的提示
实际上,我在java中发现了类似的东西
以下是C#改编:
class Class1
{
public static void Run()
{
doTopologicalTest();
}
private static void doTopologicalTest()
{
List<Field> fields = new List<Field>();
fields.Add(new Field() { Name = "FirstName" });
fields.Add(new Field()
{
Name = "FullName",
DependsOn = new[] { "FirstName", "LastName" }
});
fields.Add(new Field()
{
Name = "Age",
DependsOn = new[] { "DateOfBirth" }
});
fields.Add(new Field() { Name = "LastName" });
fields.Add(new Field() { Name = "DateOfBirth" });
foreach (var field in fields)
{
Console.WriteLine(field.Name);
if(field.DependsOn != null)
foreach (var item in field.DependsOn)
{
Console.WriteLine(" -{0}",item);
}
}
Console.WriteLine("\n...Sorting...\n");
int[] sortOrder = getTopologicalSortOrder(fields);
for (int i = 0; i < sortOrder.Length; i++)
{
var field = fields[sortOrder[i]];
Console.WriteLine(field.Name);
if (field.DependsOn != null)
foreach (var item in field.DependsOn)
{
Console.WriteLine(" -{0}", item);
}
}
}
private static int[] getTopologicalSortOrder(List<Field> fields)
{
TopologicalSorter g = new TopologicalSorter(fields.Count);
Dictionary<string, int> _indexes = new Dictionary<string, int>();
//add vertices
for (int i = 0; i < fields.Count; i++)
{
_indexes[fields[i].Name.ToLower()] = g.AddVertex(i);
}
//add edges
for (int i = 0; i < fields.Count; i++)
{
if (fields[i].DependsOn != null)
{
for (int j = 0; j < fields[i].DependsOn.Length; j++)
{
g.AddEdge(i,
_indexes[fields[i].DependsOn[j].ToLower()]);
}
}
}
int[] result = g.Sort();
return result;
}
class Field
{
public string Name { get; set; }
public string[] DependsOn { get; set; }
}
}
Class1类
{
公共静态无效运行()
{
点拓扑测试();
}
私有静态void点拓扑测试()
{
列表字段=新列表();
添加(新字段(){Name=“FirstName”});
fields.Add(新字段()
{
Name=“FullName”,
DependsOn=new[]{“FirstName”,“LastName”}
});
fields.Add(新字段()
{
Name=“Age”,
DependsOn=new[]{“出生日期”}
});
添加(新字段(){Name=“LastName”});
添加(新字段(){Name=“DateOfBirth”});
foreach(字段中的变量字段)
{
Console.WriteLine(字段名称);
如果(field.DependsOn!=null)
foreach(字段DependsOn中的变量项)
{
Console.WriteLine(“-{0}”,项);
}
}
Console.WriteLine(“\n…排序…\n”);
int[]sortOrder=getTopologicalSortOrder(字段);
for(int i=0;i
以及TopologicalSort.cs的代码
class TopologicalSorter
{
#region - Private Members -
private readonly int[] _vertices; // list of vertices
private readonly int[,] _matrix; // adjacency matrix
private int _numVerts; // current number of vertices
private readonly int[] _sortedArray;
#endregion
#region - CTors -
public TopologicalSorter(int size)
{
_vertices = new int[size];
_matrix = new int[size, size];
_numVerts = 0;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
_matrix[i, j] = 0;
_sortedArray = new int[size]; // sorted vert labels
}
#endregion
#region - Public Methods -
public int AddVertex(int vertex)
{
_vertices[_numVerts++] = vertex;
return _numVerts - 1;
}
public void AddEdge(int start, int end)
{
_matrix[start, end] = 1;
}
public int[] Sort() // toplogical sort
{
while (_numVerts > 0) // while vertices remain,
{
// get a vertex with no successors, or -1
int currentVertex = noSuccessors();
if (currentVertex == -1) // must be a cycle
throw new Exception("ERROR: Graph has cycles");
// insert vertex label in sorted array (start at end)
_sortedArray[_numVerts - 1] = _vertices[currentVertex];
deleteVertex(currentVertex); // delete vertex
}
// vertices all gone; return sortedArray
return _sortedArray;
}
#endregion
#region - Private Helper Methods -
// returns vert with no successors (or -1 if no such verts)
private int noSuccessors()
{
for (int row = 0; row < _numVerts; row++)
{
bool isEdge = false; // edge from row to column in adjMat
for (int col = 0; col < _numVerts; col++)
{
if (_matrix[row, col] > 0) // if edge to another,
{
isEdge = true;
break; // this vertex has a successor try another
}
}
if (!isEdge) // if no edges, has no successors
return row;
}
return -1; // no
}
private void deleteVertex(int delVert)
{
// if not last vertex, delete from vertexList
if (delVert != _numVerts - 1)
{
for (int j = delVert; j < _numVerts - 1; j++)
_vertices[j] = _vertices[j + 1];
for (int row = delVert; row < _numVerts - 1; row++)
moveRowUp(row, _numVerts);
for (int col = delVert; col < _numVerts - 1; col++)
moveColLeft(col, _numVerts - 1);
}
_numVerts--; // one less vertex
}
private void moveRowUp(int row, int length)
{
for (int col = 0; col < length; col++)
_matrix[row, col] = _matrix[row + 1, col];
}
private void moveColLeft(int col, int length)
{
for (int row = 0; row < length; row++)
_matrix[row, col] = _matrix[row, col + 1];
}
#endregion
}
类拓扑排序器
{
#地区-私人会员-
私有只读int[]\u顶点;//顶点列表
私有只读int[,]_矩阵;//邻接矩阵
private int _numVerts;//当前顶点数
私有只读int[]\u-sortedArray;
#端区
#区域因素-
公共拓扑排序器(整数大小)
{
_顶点=新整数[大小];
_矩阵=新整数[大小,大小];
_numVerts=0;
对于(int i=0;i0)//保留顶点时,
{
//获取没有后继对象的顶点,或-1
int currentVertex=noSuccessors();
if(currentVertex==-1)//必须是一个循环
抛出新异常(“错误:图形有循环”);
//在排序数组中插入顶点标签(从末尾开始)
_sortedArray[\u numVerts-1]=\u顶点[currentVertex];
deleteVertex(currentVertex);//删除顶点
}
//顶点都消失了;回到Darray
返回(darray);;
}
#端区
#区域-私有助手方法-
//返回没有后继项的vert(如果没有后继项,则返回-1)