生成唯一整除整数对时,List.Contains方法无法正确检测重复列表
生成唯一整数对的重复问题与优化方案
问题根源:List.Contains的引用比较逻辑
你遇到的重复问题,核心原因是**List<int>是引用类型**,List<T>.Contains()默认比较的是对象的引用地址,而非列表内的元素内容。每次执行divSet = new List<int> { x, y }都会创建一个新的列表对象,即使两个列表的元素完全相同,它们的引用地址也不一样,因此Contains()会错误地认为这个整数对不存在,导致重复添加。
修复方案:替换引用比较为内容比较
方法1:使用Any()手动检查元素匹配
修改判断重复的逻辑,遍历已有列表逐一比较元素内容:
// 替换原有的Contains判断 if (!uniqueDivSets.Any(set => set[0] == divSet[0] && set[1] == divSet[1])) { uniqueDivSets.Add(divSet); }
方法2:使用值类型存储整数对(更推荐)
用ValueTuple<int, int>代替List<int>存储整数对,值类型的比较逻辑是基于内容而非引用,这样Contains()就能正常工作:
// 调整变量类型 List<(int, int)> uniqueDivSets = new List<(int, int)>(); // 生成整数对时直接用值元组 var divSet = (x, y); if (!uniqueDivSets.Contains(divSet)) { uniqueDivSets.Add(divSet); }
性能优化:替换递归为预生成+随机抽取
你的递归实现会反复调用自身直到凑够3组,存在栈溢出风险且效率低下。更优的方式是预先生成所有符合条件的整数对,再随机抽取3个唯一的:
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { int start = 2; int end = 8; Random rand = new Random(); // 预生成所有符合要求的整数对(x%y==0且x≠y) var validPairs = new List<(int Dividend, int Divisor)>(); for (int x = start; x < end; x++) { for (int y = start; y < end; y++) { if (x % y == 0 && x != y) { validPairs.Add((x, y)); } } } // 随机打乱后取前3个,保证唯一性 var uniqueDivSets = validPairs.OrderBy(_ => rand.Next()).Take(3).ToList(); // 输出结果 foreach (var pair in uniqueDivSets) { Console.WriteLine($"{pair.Dividend} {pair.Divisor}"); } } }
这种方式的优势:
- 避免了反复随机生成无效数的浪费
- 逻辑清晰,无递归栈溢出风险
- 保证生成的3组绝对唯一
内容的提问来源于stack exchange,提问作者Firefingertips
相关产品推荐
相关产品推荐

