什么是返回List <string>元素的微优化和最优雅方式,这些元素仅在其他List <string>中出现一次

时间:2015-12-02 05:57:12

标签: c# .net algorithm

这是我今天面试的一个问题:

  

&#34;给定一个字符串列表,返回一个只有唯一字符串的列表&#34;

我很好奇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;

用一种听起来居高临下的声音,好像我做错了什么。

  • 它有什么逻辑错误吗?
  • 有没有办法实现更高内存和处理效率的解决方案?
  • 面试官是否可能正在寻找LINQ-esque解决方案?为什么他似乎不喜欢我的?
  • 有没有办法让这个更紧凑?

5 个答案:

答案 0 :(得分:6)

基于更新的问题,这是LINQ的一种方式:

var src = new List<string>() { "dog", "cat", "elephant", "dog", "dog" } ;
src.GroupBy(x => x).Where(y => y.Count() == 1).ToList();

Demo

答案 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)

由于这是一个面试问题,你需要考虑面试官对这个问题的看法。

  1. 如果他想知道你在LINQ上的技巧,你应该给出LINQ代码。 (像其他答案一样)

  2. 如果他想测试你的算法,你需要编写纯C风格的程序而不是使用内置库。在这种情况下,您的代码可以改进,因为它的内存比预期的多。可以优化程序中的变量output。输入参数已包含所有字符串,无需再次复制。此外counter是过度杀戮,您只需要int[]来存储元素数量。

  3. 有时面试官想测试受访者解决问题的方法。当你被问到这个问题时,你可以问面试官:

    (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();