查找数组中特定字符串的所有索引的更快方法

时间:2018-07-15 13:13:47

标签: c# arrays performance

下面的代码用于查找一个字符串的所有索引,这些索引在数组中可能只出现一次,但是代码执行速度不是很快。有人知道更快,更有效的方法来查找数组中的唯一字符串吗?

using System;
using System.Collections.Generic;
using System.Linq;

public static class EM
{
    // Extension method, using Linq to find indices.
    public static int[] FindAllIndicesOf<T>(this IEnumerable<T> values, T val)
    {
        return values.Select((b,i) => Equals(b, val) ? i : -1).Where(i => i != -1).ToArray();
    }
}


public class Program
{
    public static string FindFirstUniqueName(string[] names)
    {
        var results = new List<string>();
        for (var i = 0; i < names.Length; i++)
        {
            var matchedIndices = names.FindAllIndicesOf(names[i]);
            if (matchedIndices.Length == 1)
            {
                results.Add(names[matchedIndices[0]]);
                break;
            }
        }
        return results.Count > 0 ? results[0] : null;
    }


    public static void Main(string[] args)
    {
        Console.WriteLine("Found: " + FindFirstUniqueName(new[]
            {
                "James",
                "Bill",
                "Helen",
                "Bill",
                "Helen",
                "Giles",
                "James",
            }
        ));
    }
}

1 个答案:

答案 0 :(得分:0)

您的解决方案具有O(n ^ 2)复杂度。您可以使用Hash-Map将其改进为O(n)。

考虑一个哈希映射,在每个哈希映射中您的原始列表中的每个哈希名称都有其重复发生的次数。现在,您要做的就是检查字典中的所有键(又名哈希图)并返回等于1的所有键。请注意,检查此字典中的所有键小于o(n),因为它不能容纳大于n的值。名称。

要在C#中实现此词典,请执行以下操作:

List<string> stuff = new List<string>();
var groups = stuff.GroupBy(s => s).Select(
    s => new { Stuff = s.Key, Count = s.Count() });
var dictionary = groups.ToDictionary(g => g.Stuff, g => g.Count);

Taken from herejuharr的建议

O(n)是最低要求,因为您必须至少遍历所有名称一次。