求合并重叠时间段的算法 本帖最后由 zhlei616 于 2011-02-28 09:01:02 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 DateTime.Compare来比较List<DataRow> lstRows = new List<DataRow>();var result = lstRows.Where(row => DateTime.Now >= Convert.ToDateTime(row["StartTime"]) && DateTime.Now <= Convert.ToDateTime(row["EndTime"]));if (result.Count() > 0) // 交叉 大哥,在博客园已经给你回复了:http://home.cnblogs.com/q/22617/http://www.cnblogs.com/durongjian/archive/2011/03/01/1968044.html 虽然功能实现得还是不错的,不过个人感觉欠考虑,不是效率问题,而是准确度问题。比方说,后面一行记录的结束时间如果也小于前面一行记录,那么结束时间就不应该继续拿后面一行记录了。如果List内的数据未经过排序,那么这样做肯定得不到想要的结果。鉴于数据一般优先加载到DataTable中,在DataTable中使用筛选更加好。 非常感谢你的意见,程序现已更改:http://www.cnblogs.com/durongjian/archive/2011/03/01/1968044.html 这个问题看起来不复杂啊首先把数据读入DataTable dt里,然后 static void CombineData() { DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("StartTime", Type.GetType("System.DateTime"))); dt.Columns.Add(new DataColumn("EndTime", Type.GetType("System.DateTime"))); DataRow row = dt.NewRow(); row[0] = DateTime.Parse("06:10:58"); row[1] = DateTime.Parse("08:15:28"); dt.Rows.Add(row); row = dt.NewRow(); row[0] = DateTime.Parse("07:38:56"); row[1] = DateTime.Parse("10:34:45"); dt.Rows.Add(row); row = dt.NewRow(); row[0] = DateTime.Parse("10:55:00"); row[1] = DateTime.Parse("11:34:00"); dt.Rows.Add(row); row = dt.NewRow(); row[0] = DateTime.Parse("13:09:34"); row[1] = DateTime.Parse("17:45:23"); dt.Rows.Add(row); row = dt.NewRow(); row[0] = DateTime.Parse("14:23:12"); row[1] = DateTime.Parse("15:24:14"); dt.Rows.Add(row); row = dt.NewRow(); row[0] = DateTime.Parse("16:14:25"); row[1] = DateTime.Parse("17:52:15"); dt.Rows.Add(row); for (int i = dt.Rows.Count - 1; i >= 1; i--) { //从后往前判断 if (Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) > Convert.ToDateTime(dt.Rows[i]["StartTime"].ToString()) && Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) < Convert.ToDateTime(dt.Rows[i]["EndTime"].ToString())) { dt.Rows[i - 1]["EndTime"] = dt.Rows[i]["EndTime"]; dt.Rows.RemoveAt(i); } else if (Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) > Convert.ToDateTime(dt.Rows[i]["StartTime"].ToString()) && Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) > Convert.ToDateTime(dt.Rows[i]["EndTime"].ToString())) { dt.Rows.RemoveAt(i); i++; } } foreach (DataRow r in dt.Rows) { Console.WriteLine(r[0].ToString()+" "+r[1].ToString()); } Console.ReadLine(); }中午没睡觉,呵呵,好在整出来个结果 贴图贴不上,copy上来结果2011-03-02 6:10:58 2011-03-02 10:34:452011-03-02 10:55:00 2011-03-02 11:34:002011-03-02 13:09:34 2011-03-02 17:52:15 感谢大家的回复,尤其是天行健兄,原来大家都是CSDN和博客园两边逛啊,哈哈~~~天行健和superhoy的代码我已运行过,都成功的解决了此问题,也感谢青龙白虎和jingjiting26和建议哈由于昨天需求变得更复杂了点,所以结贴前我也把我现在用的算法公布一下吧需求后来又加入了另一组时间段集合,从第一组时间段集合中排除掉第二组时间段集合,如下图所以我现在的算法是new了个bool[86400]的数组(一天86400秒),默认所有值为false将第一组所有时间段相应的秒设为true,在把第二组所有时间段相应的秒设为false最后剩下来的为true的秒数就是所要的结果,但此算法仅限于算一天内的时间段86400个boolean占用内存86K(如果我记得没错的话,一个bool一字节),经过测试跑一天的执行下来也就0.0几秒但如果周期是一月或一年就不能用此方法了 远端服务器某个目录下文件的遍历查询 如何避免取到ID相同的控件呢??? realplayer那种进度条怎么搞 修改过的行在datagrid中高亮显示的问题? c# 写的windows应用程序,怎么部署倒是用这的机器上? 要怎么样编写进度条才合理? 请问如何实时更新数据 .net技术交流群号 如何在GridView根据某列字段控制显示记录 共同探讨 请教哈希 C# 如何实现套打???
List<DataRow> lstRows = new List<DataRow>();var result = lstRows.Where(row =>
DateTime.Now >= Convert.ToDateTime(row["StartTime"]) &&
DateTime.Now <= Convert.ToDateTime(row["EndTime"]));if (result.Count() > 0) // 交叉
http://home.cnblogs.com/q/22617/
http://www.cnblogs.com/durongjian/archive/2011/03/01/1968044.html
http://www.cnblogs.com/durongjian/archive/2011/03/01/1968044.html
首先把数据读入DataTable dt里,然后 static void CombineData()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("StartTime", Type.GetType("System.DateTime")));
dt.Columns.Add(new DataColumn("EndTime", Type.GetType("System.DateTime"))); DataRow row = dt.NewRow();
row[0] = DateTime.Parse("06:10:58");
row[1] = DateTime.Parse("08:15:28");
dt.Rows.Add(row); row = dt.NewRow();
row[0] = DateTime.Parse("07:38:56");
row[1] = DateTime.Parse("10:34:45");
dt.Rows.Add(row); row = dt.NewRow();
row[0] = DateTime.Parse("10:55:00");
row[1] = DateTime.Parse("11:34:00");
dt.Rows.Add(row); row = dt.NewRow();
row[0] = DateTime.Parse("13:09:34");
row[1] = DateTime.Parse("17:45:23");
dt.Rows.Add(row); row = dt.NewRow();
row[0] = DateTime.Parse("14:23:12");
row[1] = DateTime.Parse("15:24:14");
dt.Rows.Add(row); row = dt.NewRow();
row[0] = DateTime.Parse("16:14:25");
row[1] = DateTime.Parse("17:52:15");
dt.Rows.Add(row); for (int i = dt.Rows.Count - 1; i >= 1; i--)
{
//从后往前判断
if (Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) > Convert.ToDateTime(dt.Rows[i]["StartTime"].ToString()) && Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) < Convert.ToDateTime(dt.Rows[i]["EndTime"].ToString()))
{
dt.Rows[i - 1]["EndTime"] = dt.Rows[i]["EndTime"];
dt.Rows.RemoveAt(i);
}
else if (Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) > Convert.ToDateTime(dt.Rows[i]["StartTime"].ToString()) && Convert.ToDateTime(dt.Rows[i - 1]["EndTime"].ToString()) > Convert.ToDateTime(dt.Rows[i]["EndTime"].ToString()))
{
dt.Rows.RemoveAt(i);
i++;
}
} foreach (DataRow r in dt.Rows)
{
Console.WriteLine(r[0].ToString()+" "+r[1].ToString());
}
Console.ReadLine();
}
中午没睡觉,呵呵,好在整出来个结果
2011-03-02 6:10:58 2011-03-02 10:34:45
2011-03-02 10:55:00 2011-03-02 11:34:00
2011-03-02 13:09:34 2011-03-02 17:52:15
天行健和superhoy的代码我已运行过,都成功的解决了此问题,也感谢青龙白虎和jingjiting26和建议哈
由于昨天需求变得更复杂了点,所以结贴前我也把我现在用的算法公布一下吧
需求后来又加入了另一组时间段集合,从第一组时间段集合中排除掉第二组时间段集合,如下图
所以我现在的算法是new了个bool[86400]的数组(一天86400秒),默认所有值为false
将第一组所有时间段相应的秒设为true,在把第二组所有时间段相应的秒设为false
最后剩下来的为true的秒数就是所要的结果,但此算法仅限于算一天内的时间段
86400个boolean占用内存86K(如果我记得没错的话,一个bool一字节),经过测试跑一天的执行下来也就0.0几秒
但如果周期是一月或一年就不能用此方法了