前言
没有找到合适的方法。一、前景
根据起点和终点构建出一条连续的线段,而分线段集合是乱序的,并不是1-2,2-3,3-4有序的,所以需要在乱序的分线段中构建成一条有序的线段,可以是正向的,也可以是反向的。
二、使用步骤
1.新建Condition类和Line类
代码如下(示例):
class Condition
{
/// <summary>
/// 起点
/// </summary>
public string Start { get; set; }
/// <summary>
/// 终点
/// </summary>
public string Stop { get; set; }
}
class Line
{
/// <summary>
/// 起点
/// </summary>
public string StartId { get; set; }
/// <summary>
/// 终点
/// </summary>
public string StopId { get; set; }
}
2.编写算法
代码如下(示例):
/// <summary>
/// 输入起点和终点,返回起点到终点连接的一条线段。
/// </summary>
/// <param name="lines">乱序的分线段集合</param>
/// <param name="conditions">查询条件集合</param>
/// <returns></returns>
public static List<string> GetLinesByStartAndStop(List<Line> lines, List<Condition> conditions)
{
List<string> result = new List<string>();
if (lines.Count <= 0) return null;
foreach (var item in conditions)
{
string startId = item.Start;
string endId = item.Stop;
//循环次数
int count = lines.Count;
if (count <= 0) continue;
List<string> childResult = new List<string>();
//若起始点和终止点都为空,那么就是整条线段。
if (string.IsNullOrEmpty(startId) && string.IsNullOrEmpty(endId))
{
foreach (var enroute in lines)
{
childResult.Add($"{enroute.StartId}-{enroute.StopId}");
}
result.AddRange(childResult);
continue;
}
//一段线段的查到直接插入返回
var startIdAndEndId = lines.FirstOrDefault(p => p.StartId == startId && p.StopId == endId);
if (startIdAndEndId != null)
{
result.Add($"{startIdAndEndId.StartId}-{startIdAndEndId.StopId}");
continue;
}
var endIdAndStartId = lines.FirstOrDefault(p => p.StartId == endId && p.StopId == startId);
if (endIdAndStartId != null)
{
result.Add($"{endIdAndStartId.StartId}-{endIdAndStartId.StopId}");
continue;
}
//多段线段
bool isReverse = false;//是否反向
//先正向找,找不到终点清空数据,再反向找,反向找不到终点也清空数据
{
//第一种情况,正向查;开始点在StartId上,结束点在EndID上。
var first = lines.FirstOrDefault(p => p.StartId == startId);
if (first == null)
{
isReverse = true;
}
else
{
childResult.Add($"{first.StartId}-{first.StopId}");
string tempId = first.StopId;
for (int i = 0; i < count; i++)
{
var second = lines.FirstOrDefault(p => p.StartId == tempId);
if (second == null)
{
isReverse = true;
childResult.Clear();
break;
}
tempId = second.StopId;
childResult.Add($"{second.StartId}-{second.StopId}");
if (second.StopId.Trim() == endId.Trim()) break;
}
}
}
if (isReverse)
{
//第二种情况,反向查;开始点在StopId上,结束点在StartId上。
var first = lines.FirstOrDefault(p => p.StopId == startId);
if (first != null)
{
childResult.Add($"{first.StopId}-{first.StartId}");
string tempId = first.StartId;
for (int i = 0; i < count; i++)
{
var second = lines.FirstOrDefault(p => p.StopId == tempId);
if (second == null)
{
childResult.Clear();
break;
}
tempId = second.StartId;
childResult.Add($"{second.StopId}-{second.StartId}");
if (second.StartId.Trim() == endId.Trim()) break;
}
}
}
result.AddRange(childResult);
}
return result;
}
3.如何使用
static void Main(string[] args)
{
List<Line> lines = new List<Line>();
lines.Add(new Line() { StartId = "2", StopId = "3" });
lines.Add(new Line() { StartId = "5", StopId = "6" });
lines.Add(new Line() { StartId = "4", StopId = "5" });
lines.Add(new Line() { StartId = "3", StopId = "4" });
lines.Add(new Line() { StartId = "1", StopId = "2" });
List<Condition> conditions = new List<Condition>();
conditions.Add(new Condition { Start = "1", Stop = "6" });
conditions.Add(new Condition { Start = "6", Stop = "1" });
var result = GetLinesByStartAndStop(lines, conditions);
foreach (var item in result)
{
Console.WriteLine(item);
}
}