查找集合中不重复的数字列表.这可以做得更高效/更短的代码

本文关键字:高效 代码 集合 列表 数字 查找 | 更新日期: 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;)

虽然你的最终目标是效率,但我会使用最简单的代码(我认为这是),然后在分析器告诉我时进行优化。