C#根据起点和终点构建出一条连续的线段

前言

没有找到合适的方法。

一、前景

根据起点和终点构建出一条连续的线段,而分线段集合是乱序的,并不是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);
    }

}

总结

使用此方法可以快速的得出正向或反向的连续线段,当然线段在这里仅仅是个例子,也可以是其他对象。
posted @ 2022-04-05 23:08  小堂子  阅读(328)  评论(0)    收藏  举报