C# 區間合并(Linq To Sql)

來源:互聯網
上載者:User

一、項目問題

       C#的list<point>類型中存入了很多區間類似於(a--b),Point.x存入的是開始位置,Point.Y存入的是結束位置。list<point>中存入了很多這樣的

點,例如1--4,3---8,9--20,17--25。

而目前的問題是要把這些重合的區間從新合并成多個區間,例如上邊四個區間應該合并為:1--8和9--25 。最後的list<point>類型中應該沒有再重複的區間。

二、LInq方面的解決方案(一高手提供)

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{    class Program    {        static void Main(string[] args)        {            List<Point> data = new List<Point>()            {                new Point() { X = 1, Y = 4 },                new Point() { X = 3, Y = 8 },                new Point() { X = 9, Y = 20 },                new Point() { X = 17, Y = 25 }            };            data.ForEach(x =>            {                if (data.Where(y => y != x).Any(y => y.X <= x.Y && y.Y >= x.X))                {                    var desc = data.Where(y => y != x).First(y => y.X <= x.Y && y.Y >= x.X);//返回除自己以外的滿足條件的區間                    x.X = desc.X > x.X ? x.X : desc.X;                    x.Y = desc.Y > x.Y ? desc.Y : x.Y;                }            });            data = data.GroupBy(x => new { x.X, x.Y }).Select(x => new Point() { X = x.Key.X, Y = x.Key.Y }).ToList();//合并list<point>中重複的區間            foreach (var item in data)            {                Console.WriteLine(item);            }        }    }    class Point    {        public int X { get; set; }        public int Y { get; set; }        public override string ToString()        {            return string.Format("X = {0}, Y = {1}.", X, Y);        }    }}

     上面的代碼輸出為:1--8和9--25.

三、非Ling to Sql的解決方案(一)

         因為我自己的版本面向的.Net FrameWork版本是2.0的,而只有3.5的.net FrameWork版本才支援Linq,所以我按照上面的辦法寫了跟上述功能相似的犯法,類似於Where和Group的用法,經過自己的測試達到了上述的要求,代碼如下:

        List<PointA> data = new List<PointA>         {         new PointA() { X = 18,Y = 26},                new PointA() { X = 3, Y = 8 },                new PointA() { X = 1, Y = 4 },                new PointA() { X = 9, Y = 20 },                new PointA() { X = 17, Y = 25 }        };        public void sort(List<PointA> data)        {            data.ForEach(x => {                PointA temp = new PointA();                temp = innerSort(data, x);//返回第一個滿足條件的PontA類                if (0!=temp.X && 0!=temp.Y)                {                    x.X = temp.X > x.X ? x.X : temp.X;                    x.Y = temp.Y > x.Y ? temp.Y : x.Y;                }            });            /*重複資料刪除資料*/            for (int i = 0; i < data.Count - 1; i++)            {                for (int j = data.Count - 1; j > i; j--)                {                    if (data[j].X==data[i].X &&data[j].Y==data[i].Y)                    {                        data.Remove(data[j]);                    }                }            }            Console.WriteLine(data);        }        /*此方法用來返回第一個滿足條件的PointA的區間*/      private PointA innerSort(List<PointA> list,PointA x)        {        PointA result = new PointA();        foreach (PointA y in list)        {            if (y != x && y.X <= x.Y && y.Y >= x.X)            {                result = y;                break;            }        }        return result;        }    }    class PointA    {        public int X { get; set; }        public int Y { get; set; }        public override string ToString()        {            return string.Format("X = {0}, Y = {1}.", X, Y);        }

四、非Linq解決方案(二)

         上邊的兩個方法只能合并區間相鄰的時候,比如(1,4)、(2、8),會輸出(1,8),但是當輸入(1,4)、(8,15)、(2,10)的時候輸出結果是(1,10)、(8,15),顯然結果是不正確的,所以自己又改進了以前的方法,如下所示:

List<PointA> data = new List<PointA>         {         new PointA() { X = 18,Y = 26},                new PointA() { X = 3, Y = 8 },                new PointA() { X = 1, Y = 4 },                new PointA() { X = 9, Y = 20 },                new PointA() { X = 17, Y = 25 }        };        /// <summary>        /// 雙重迴圈的合并演算法,實現了任意多個區間的合并        /// 思路:外迴圈,從第一個到最後一個        /// 內迴圈,找到符合合并條件的選項,將合并後的資料儲存在data[i-1]中,然後刪除已經被合并的        /// 資料,同時將內迴圈的m初始化0,從新開始下一輪的迴圈,m!=i-1是為了限定在相等的時候不要        /// 刪除資料        /// </summary>        /// <param name="data"></param>        public void SortTest(List<PointF> data)        {            for (int i = 1; i < data.Count; i++)            {                for (int m = i; m < data.Count; m++)                {                    if (data[m].X <= data[i-1].Y && data[m].Y >= data[i-1].X &&m!=i-1)                    {                        PointF tempPoint = new PointF();                        tempPoint.X = data[i-1].X > data[m].X ? data[m].X : data[i-1].X;                        tempPoint.Y = data[i-1].Y > data[m].Y ? data[i-1].Y : data[m].Y;                        data[i-1] = tempPoint;//結構體是值傳遞,要修改只能通過這種方式                        data.Remove(data[m]);                        m = 0;//從頭開始此次迴圈合并                    }                }            }        }    }    class PointA    {        public int X { get; set; }        public int Y { get; set; }        public override string ToString()        {            return string.Format("X = {0}, Y = {1}.", X, Y);        }

五、總結

      從這個例子可以看出使用Linq To Sql可以使程式的代碼量大大減少,並且效率也很高。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.