查找集合中不重复的数字列表.这可以做得更高效/更短的代码
本文关键字:高效 代码 集合 列表 数字 查找 | 更新日期: 2023-09-27 18:03:14
static IEnumerable<T> FindUniqueNumbersInCollection<T>(ICollection<T> value)
{
Dictionary<T, byte> hash = new Dictionary<T, byte>();
foreach (T val in value)
{
if (hash.ContainsKey(val)) { hash[val] = 1; continue; }
hash.Add(val, 0);
}
List<T> unique = new List<T>();
foreach (KeyValuePair<T, byte> kvp in hash)
{
if (kvp.Value == 0) unique.Add(kvp.Key);
}
return unique;
}
编辑:
我认为这最终是正确的。:)
var dict = new Dictionary<T, bool>();
foreach (var v in value)
dict[v] = dict.ContainsKey(v);
foreach (var pair in dict)
if (!pair.Value)
yield return pair.Key; //Algorithmically, as fast as possible
或者如果你想要一些LINQ:
var dict = new Dictionary<T, bool>();
foreach (var v in value)
dict[v] = dict.ContainsKey(v);
return dict.Keys.Where(k => !dict[k]); //*COULD* be slower on lots of collisions
或者
var dict = new Dictionary<T, bool>();
foreach (var v in value)
dict[v] = dict.ContainsKey(v);
return dict.Where(p => !p.Value).Select(p => p.Key); //"Fastest".. but not really
我不会说它"更有效率"。比你的短(其实不一样——它们几乎一样),但绝对短。
如果你想要过度杀死效率(以准确性为代价),你总是可以使用布隆过滤器!
由于您返回的是IEnumerable<T>
,您可以
return hash.Where(kvp => kvp.Value == 0).Select(kvp => kvp.Key);
而不是第二个循环来延迟执行该迭代。
下面的代码将这样做(在一个语句中)。
var unqiue = new[] { 1, 1, 2, 3, 3, 4 }
.GroupBy(x => x) // groups the elements using the element value as the key
.Where(x => x.Count() == 1) // restricts to only those groups having a count of 1
.Select(x => x.Key); // selects the key from each of those groups
(你需要在你的代码文件中有using System.Linq;
)
虽然你的最终目标是效率,但我会使用最简单的代码(我认为这是),然后在分析器告诉我时进行优化。