【发布时间】:2018-12-23 05:30:28
【问题描述】:
下面的代码用于查找字符串的所有索引,这些索引可能在数组中只出现一次,但代码不是很快。有人知道在数组中查找唯一字符串的更快更有效的方法吗?
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",
}
));
}
}
【问题讨论】:
-
这个 O(n^2)。为什么不将每个名称插入 Hashmap (name->numOfRecurrence) 然后返回映射到 1 的所有名称 - 这将是 O(n)
-
你可以试试
names.GroupBy(x => x).Where(grp => grp.Count() == 1).Select(grp => grp.First()).ToList() -
@DavidWinder 听起来不错,但是如何创建一个以名称为键、重复为值的 HashMap(字典),最好没有循环?例如。类似于
var dictionary = sequence.ToDictionary(item => item.Key, item => item.Value) -
@BadmintonCat 不管你做什么,你能得到的都是O(n),所以即使你使用Linq,在幕后它也会使用一个循环。
标签: c# arrays performance