这是我今天面试的一个问题:
"给定一个字符串列表,返回一个只有唯一字符串的列表"
我很好奇Skeet认证的答案是什么。
我自己的答案是
public static List<string> sans_repeats ( List<string> input )
{
Dictoinary<string,int> counter = new Dictionary<string,int>();
List<string> output = new List<string>();
foreach ( string S in input )
{
if ( counter.HasKey(S) ) counter[S] = 1;
else ++count[S];
}
foreach ( KeyValuePair<string,int> entry in counter )
if ( entry.Value == 1 ) output.Add(entry.Key);
return output;
}
和采访说
用一种听起来居高临下的声音,好像我做错了什么。&#34;嗯,这是一种方法......&#34;
答案 0 :(得分:6)
基于更新的问题,这是LINQ的一种方式:
var src = new List<string>() { "dog", "cat", "elephant", "dog", "dog" } ;
src.GroupBy(x => x).Where(y => y.Count() == 1).ToList();
答案 1 :(得分:3)
最简单的方法,使用内置函数:
List<string> distinctList = input.Distinct();
https://msdn.microsoft.com/library/bb920306(v=vs.90).aspx
或者,检查输出列表中是否已存在当前项目,如果存在,则继续:
List<string> output = new List<string>();
foreach (string S in input)
{
if (output.Contains(S)) continue;
output.Add(S);
}
修改强>
根据您的评论,您只需要仅发生一次的项目:
Dictionary<string, int> stringCount = new Dictionary<string, int>();
foreach (string S in input)
{
if (stringCount.ContainsKey(S))
{
stringCount[S]++;
}
else
{
stringCount.Add(S, 1);
}
}
var output = stringCount.Where(x => x.Value == 1).ToList();
答案 2 :(得分:2)
由于这是一个面试问题,你需要考虑面试官对这个问题的看法。
如果他想知道你在LINQ上的技巧,你应该给出LINQ代码。 (像其他答案一样)
如果他想测试你的算法,你需要编写纯C风格的程序而不是使用内置库。在这种情况下,您的代码可以改进,因为它的内存比预期的多。可以优化程序中的变量output
。输入参数已包含所有字符串,无需再次复制。此外counter
是过度杀戮,您只需要int[]
来存储元素数量。
有时面试官想测试受访者解决问题的方法。当你被问到这个问题时,你可以问面试官:
(1)返回的列表是否应该与输入列表相同,或者创建新列表是否可以接受?
(2)元素最多出现多少次?如有必要,请使用byte[]
来存储计数,而不是int[]
。
答案 3 :(得分:0)
Linq是一个不错的选择,但是如果你想要一个集合,为什么在Dictionary
可能更合适时使用HashSet
。
var strings = new[] { "a", "a", "b", "c" };
var hash = new HashSet<string>(strings);
hash.Dump(); // a, b, c
答案 4 :(得分:0)
这是另一种有效的方法,使用HashSet.Add方法实际添加项目的事实,只有当项目不在集合中时才返回true。代码是自我解释的。
var uniqueSet = new HashSet<string>();
var duplicateSet = new HashSet<string>(input.Where(item => !uniqueSet.Add(item)));
var output = input.Where(item => !duplicateSet.Contains(item)).ToList();