• 全部
  • C#综合技术
  • C#互联网桌面应用
  • AppLauncher
  • WinForm&WPF
  • C#开发新技术
  • 问答

关于两集合对比,请教各位高手一个高效的算法或问题解决办法

candypill 2020-12-09 06:50:54
关于两集合对比,请教各位高手一个高效的算法或问题解决办法

现有LIST1和LIST2, 行*列=5000*5

表1 第一学期
姓名 语文 数学 英语 物理
老大 10 20 30 40
老二 10 20 30 40
老三 10 20 30 40
老四 10 20 30 40
.
.
.

表2 第二学期
姓名 语文 数学 英语 物理
老二 10 20 30 50
老大 10 20 30 40
老三 10 20 40 40
老四 10 20 30 40
.
.
.
存放名字所在行位置会变,名字没有重复
想找出第二学期考式比第一学期单科高出10分的人,不管哪科高出10分都推出名字
两层循环实在是太慢了
例,结果推出老二,老三
另:处理这类问题有没有先放到库里落地,对比完,再拿结果这样的解决办法
...全文
3011 点赞 收藏 32
写回复
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
wllllll 2020-12-25
如果你还想块,可以改数据成Int16。差不多就是极限了,别折腾了;额
回复
wllllll 2020-12-25
16楼的办法已经可以了,你编译成Release。会更块,别去找别的办法了,快不了了
回复
正怒月神 2020-12-14
引用 21 楼 candypill 的回复:
[quote=引用 20 楼 正怒月神 的回复:]如果一定要追求效率。 那我感觉你重写compare方法,只比较分数,应该是最快的。
var query = from val1 in list1 join val2 in list2 on val1.Name equals val2.Name where (val2.Chinese >= val1.Chinese + 10 || val2.Math >= val1.Math + 10 || val2.English >= val1.English + 10 || val2.Physics >= val1.Physics + 10) select new { val1.Name }; 上面有位兄弟写的这个已经只对比分数了吧,是不是说这个还可以有更高效的写法?[/quote] 不一定,这个需要你自己测试一下,因为连表操作也是需要时间的。
回复
candypill 2020-12-13
引用 23 楼 老夏 的回复:
一个简单的方式,4个学科Dictionary遍历第一个列表设置姓名=>学科分数,然后遍历第二个列表与从Dictionary取的值对比,每行遇到一个大10的就可以
可能我对Dictionary理解还不太够,您给的思路还需要花些时间理解一下,不知道可否有简短代码支持
回复
candypill 2020-12-13
引用 27 楼 cihn2 的回复:
事先预处理一下,两个列表顺序排序同步,行数人数一致,只要循环一次就够了
这确实是个办法,多谢
回复
candypill 2020-12-13
引用 25 楼 以专业开发人员为伍 的回复:
如果是10万数据,“两层循环”比较也就1秒钟吧。你要是车上什么数据库,耗费几分钟。时间全都花在通讯和序列化上了。内存计算问题纠结“数据库”就坑爹了。
开始就是把两个FOR套一块遍历两个LIST逐个去做对比去了,效率极低。后来试用上面一位兄弟的LINQ可以在0.6-0.8秒左右。 用循环就可以把10W数据1秒搞定感觉很厉害,高手能否给个小实例学习
回复
如果是10万数据,“两层循环”比较也就1秒钟吧。你要是车上什么数据库,耗费几分钟。时间全都花在通讯和序列化上了。内存计算问题纠结“数据库”就坑爹了。
回复
在内存中做“两层循环”为什么慢?
回复
cihn2 2020-12-12
事先预处理一下,两个列表顺序排序同步,行数人数一致,只要循环一次就够了
回复
xuzuning 2020-12-12
SelectMany
回复
老夏 2020-12-11
一个简单的方式,4个学科Dictionary遍历第一个列表设置姓名=>学科分数,然后遍历第二个列表与从Dictionary取的值对比,每行遇到一个大10的就可以
回复
qq_38191951 2020-12-11
static void Main(string[] args) { List<Student> list1 = new List<Student>(); List<Student> list2 = new List<Student>(); list1.Add(new Student { Name = "老大", Chinese = 10, Math = 10, English = 20, Physics = 30 }); list1.Add(new Student { Name = "老二", Chinese = 20, Math = 30, English = 40, Physics = 30 }); list1.Add(new Student { Name = "老三", Chinese = 30, Math = 10, English = 40, Physics = 20 }); list1.Add(new Student { Name = "老四", Chinese = 10, Math = 30, English = 20, Physics = 30 }); list2.Add(new Student { Name = "老大", Chinese = 10, Math = 10, English = 20, Physics = 40 }); list2.Add(new Student { Name = "老二", Chinese = 20, Math = 30, English = 40, Physics = 30 }); list2.Add(new Student { Name = "老三", Chinese = 30, Math = 20, English = 40, Physics = 20 }); list2.Add(new Student { Name = "老四", Chinese = 10, Math = 30, English = 20, Physics = 30 }); var query = from val1 in list1 join val2 in list2 on val1.Name equals val2.Name where (val2.Chinese >= val1.Chinese + 10 || val2.Math >= val1.Math + 10 || val2.English >= val1.English + 10 || val2.Physics >= val1.Physics + 10) select new { val1.Name }; foreach (var item in query) { Console.WriteLine(item.Name); } Console.ReadKey(); } public class Student { public string Name { get; set; } public decimal Chinese { get; set; } public decimal Math { get; set; } public decimal English { get; set; } public decimal Physics { get; set; } } 就这样吧 不知数据多了 查询效率怎样 你测试一下
回复
夜空的温柔 2020-12-11
我最喜欢算法了
回复
candypill 2020-12-11
引用 20 楼 正怒月神 的回复:
如果一定要追求效率。 那我感觉你重写compare方法,只比较分数,应该是最快的。
var query = from val1 in list1 join val2 in list2 on val1.Name equals val2.Name where (val2.Chinese >= val1.Chinese + 10 || val2.Math >= val1.Math + 10 || val2.English >= val1.English + 10 || val2.Physics >= val1.Physics + 10) select new { val1.Name }; 上面有位兄弟写的这个已经只对比分数了吧,是不是说这个还可以有更高效的写法?
回复
正怒月神 2020-12-11
如果一定要追求效率。 那我感觉你重写compare方法,只比较分数,应该是最快的。
回复
candypill 2020-12-11
引用 18 楼 翘着二郎腿的程序猿 的回复:
List<Student> stuA = new List<Student>(); List<Student> stuB = new List<Student>(); stuA.Add(new Student { Id = 1, Name = "1", Age = 1 }); stuA.Add(new Student { Id = 5, Name = "5", Age = 2 }); stuB.Add(new Student { Id = 1, Name = "1", Age = 1 }); stuB.Add(new Student { Id = 2, Name = "2", Age = 2 }); stuB.Add(new Student { Id = 3, Name = "3", Age = 3 }); stuB.Add(new Student { Id = 4, Name = "4", Age = 4 }); var result = stuA.Where(a => !stuB.Exists(b => b.Id == a.Id)); //在A中存在不再B中存在 即求差集 var resc = stuA.Except(stuB, new CompareStudent()); //差集 var resj = stuA.Intersect(stuB, new CompareStudent());// 交集 var resb = stuA.Union(stuB, new CompareStudent()); //并集 var resD = stuB.Distinct(new CompareStudent()); //去重
这个怎么判断记录的内容发生过变化
回复
List<Student> stuA = new List<Student>();
List<Student> stuB = new List<Student>();
stuA.Add(new Student { Id = 1, Name = "1", Age = 1 });
stuA.Add(new Student { Id = 5, Name = "5", Age = 2 });
stuB.Add(new Student { Id = 1, Name = "1", Age = 1 });
stuB.Add(new Student { Id = 2, Name = "2", Age = 2 });
stuB.Add(new Student { Id = 3, Name = "3", Age = 3 });
stuB.Add(new Student { Id = 4, Name = "4", Age = 4 });
var result = stuA.Where(a => !stuB.Exists(b => b.Id == a.Id)); //在A中存在不再B中存在 即求差集
var resc = stuA.Except(stuB, new CompareStudent()); //差集
var resj = stuA.Intersect(stuB, new CompareStudent());// 交集
var resb = stuA.Union(stuB, new CompareStudent()); //并集
var resD = stuB.Distinct(new CompareStudent()); //去重
回复
candypill 2020-12-11
引用 16 楼 qq_38191951 的回复:
static void Main(string[] args) { List<Student> list1 = new List<Student>(); List<Student> list2 = new List<Student>(); list1.Add(new Student { Name = "老大", Chinese = 10, Math = 10, English = 20, Physics = 30 }); list1.Add(new Student { Name = "老二", Chinese = 20, Math = 30, English = 40, Physics = 30 }); list1.Add(new Student { Name = "老三", Chinese = 30, Math = 10, English = 40, Physics = 20 }); list1.Add(new Student { Name = "老四", Chinese = 10, Math = 30, English = 20, Physics = 30 }); list2.Add(new Student { Name = "老大", Chinese = 10, Math = 10, English = 20, Physics = 40 }); list2.Add(new Student { Name = "老二", Chinese = 20, Math = 30, English = 40, Physics = 30 }); list2.Add(new Student { Name = "老三", Chinese = 30, Math = 20, English = 40, Physics = 20 }); list2.Add(new Student { Name = "老四", Chinese = 10, Math = 30, English = 20, Physics = 30 }); var query = from val1 in list1 join val2 in list2 on val1.Name equals val2.Name where (val2.Chinese >= val1.Chinese + 10 || val2.Math >= val1.Math + 10 || val2.English >= val1.English + 10 || val2.Physics >= val1.Physics + 10) select new { val1.Name }; foreach (var item in query) { Console.WriteLine(item.Name); } Console.ReadKey(); } public class Student { public string Name { get; set; } public decimal Chinese { get; set; } public decimal Math { get; set; } public decimal English { get; set; } public decimal Physics { get; set; } } 就这样吧 不知数据多了 查询效率怎样 你测试一下
多谢多谢 0.6秒左右,话说。。。还能更快么?
回复
lorimoon 2020-12-10
引用 5 楼 candypill的回复:
引用 1 楼 lorimoon 的回复:
放数据库里join 一下就出结果何乐而不为?
也考虑过先落地,不过一存一取效率可能会影响不少,这只是个例子,实际情况是需要不段的对比两个表,看有没有可以不落地又高效些的办法
考虑一下linq 也可以的
回复
lorimoon 2020-12-10
引用 5 楼 candypill的回复:
引用 1 楼 lorimoon 的回复:
放数据库里join 一下就出结果何乐而不为?
也考虑过先落地,不过一存一取效率可能会影响不少,这只是个例子,实际情况是需要不段的对比两个表,看有没有可以不落地又高效些的办法
看吧,楼上说了有的数据库支持内存表。难道你的5千条数据凭空造出来的?不用写。
回复
加载更多回复
相关推荐
发帖
C#
创建于2007-09-28

10.5w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2020-12-09 06:50
社区公告

让您成为最强悍的C#开发者