C# 获取项目在C中重复的次数#

C# 获取项目在C中重复的次数#,c#,linq,list,C#,Linq,List,我正在开发一个程序,用户必须在其中输入某种字符串,程序将其存储在列表或数组中,然后计算该项重复的次数 重复次数最多的三个项目将按重复次数的降序显示(第一个项目重复10次,第二个项目重复9次,第三个项目重复8次) 听起来很简单。因为我不知道有多少人会输入一个字符串,所以我使用了一个列表,然后遵循以下示例: foreach (string value in list.Distinct()) { System.Diagnostics.Debug.WriteLine("\"{0}\" o

我正在开发一个程序,用户必须在其中输入某种字符串,程序将其存储在列表或数组中,然后计算该项重复的次数

重复次数最多的三个项目将按重复次数的降序显示(第一个项目重复10次,第二个项目重复9次,第三个项目重复8次)

听起来很简单。因为我不知道有多少人会输入一个字符串,所以我使用了一个列表,然后遵循以下示例:

foreach (string value in list.Distinct())  
{  
    System.Diagnostics.Debug.WriteLine("\"{0}\" occurs {1} time(s).", value, list.Count(v => v == value));  
}
但由于某些原因,.Distinct()不会出现在我的列表名之后。我做错什么了吗?这是否与我的C#有关,它不是C#3.0?该示例从未提及添加其他引用之类的内容

还有其他方法吗?

.Distinct()
是一种LINQ扩展方法。您需要.NET3.5+才能使用它

话虽如此,你不需要LINQ做你想做的事。您可以轻松地使用其他集合类和一些算术来获得结果

// Create a dictionary to hold key-value pairs of words and counts
IDictionary<string, int> counts = new Dictionary<string, int>();

// Iterate over each word in your list
foreach (string value in list)
{
    // Add the word as a key if it's not already in the dictionary, and
    // initialize the count for that word to 1, otherwise just increment
    // the count for an existing word
    if (!counts.ContainsKey(value))
        counts.Add(value, 1);
    else
        counts[value]++; 
}

// Loop through the dictionary results to print the results
foreach (string value in counts.Keys)
{
    System.Diagnostics.Debug
        .WriteLine("\"{0}\" occurs {1} time(s).", value, counts[value]);
}
//创建一个字典来保存单词和计数的键值对
IDictionary counts=新字典();
//迭代列表中的每个单词
foreach(列表中的字符串值)
{
//如果字典中没有该词,则将其添加为关键字,然后
//将该字的计数初始化为1,否则只需递增
//现有单词的计数
如果(!counts.ContainsKey(值))
计数。添加(值,1);
其他的
计数[值]+;
}
//循环浏览字典结果以打印结果
foreach(counts.Keys中的字符串值)
{
System.Diagnostics.Debug
.WriteLine(“{0}\”出现{1}次)。”,值,计数[值];
}

您使用的是哪个版本的.NET Framework?包含此方法的最低框架版本是.NET3.5


如果您使用的是.NET3.5或更高版本,是否有
使用System.Linq语句?如果不是,这可能就是该方法看起来不可访问的原因。该方法实际上是
Enumerable
类中定义的扩展方法,该类位于
System.Linq
命名空间中。

您必须至少使用C#3.0和.NET 3.5,并记住使用System.Linq添加

与您现有的解决方案一样,您需要.NET 3.5或更高版本才能使其正常工作,但它仍然在这里

var query = list.GroupBy(x => x).OrderByDescending(x => x.Count()).Take(3);

foreach (var result in query)
{
    Console.WriteLine("\"{0}\" occurs {1} time(s).", result.Key, result.Count());
}
如果没有C#3.0,那么就没有扩展方法

如果没有.NET3.5,那么就没有任何Linq扩展方法可以作为静态调用

您可以为其中相当多的功能添加自己的功能:

public static IEnumerable<T> Distinct(IEnumerable<T> src, IEqualityComparer<T> eCmp)
{
  Dictionary<T, bool> fakeHashSet = new Dictionary<T, bool>(eCmp);
  //When I coded for 2.0 I had my own custom HashSet<T>, but that's overkill here
  bool dummy;
  foreach(T item in src)
  {
    if(!fakeHashSet.TryGetValue(item, out dummy))
    {
      fakeHashSet.Add(item, true);
      yield return item;
    }
  }
}
public static IEnumerable<T> Distinct(IEnumerable<T> src)
{
  return Distinct(src, EqualityComparer<T>.Default);
}
public delegate TResult Func<T, TResult>(T arg);//we don't even have this :(
public static int Count(IEnumerable<T> src, Func<T, bool> predicate)
{
  int c = 0;
  foreach(T item in src)
    if(predicate(item))
      ++c;
  return c;
}
总之,我们可以用C#2.0实现很多Linq to对象,我们中的许多人都实现了,但它远没有那么友好,当然我们也无法映射到其他查询提供者

但在这种情况下,直接进行计数会更快:

Dictonary<string, int> counts = new Dictionary<string, int>();
foreach(string value in list)
{
  if(counts.ContainsKey(value))
    counts[value]++;
  else
    counts[value] = 1;
}
foreach(KeyValuePair<string, int> kvp in counts)
  System.Diagnostics.Debug.WriteLine("\"{0}\" occurs {1} time(s).", kvp.Key, kvp.Value));
dictional counts=新字典();
foreach(列表中的字符串值)
{
if(计数。容器(值))
计数[值]+;
其他的
计数[值]=1;
}
foreach(KeyValuePair kvp计数)
System.Diagnostics.Debug.WriteLine(“{0}\”出现在{1}次。”,kvp.Key,kvp.Value));

如果您使用的是3.0以前的版本,您将无法访问Distinct extension方法。您期望的结果是什么,您看到的结果是什么?只有.NET 2.0。不幸的是。对不起,我忘了提那件事。什么清单?最有可能的情况是,您在不区分相等的对象上应用了distinct。。。您可以通过使用IEquatable或IEqualityComparer@thomasleveque来解决这个问题:谢谢,我本来是这么想的,但后来我自己又猜到了。请参考system.core.dllOh man。那么我是否只下载最新版本的.NET?还是会把我的VisualStudio2005搞砸?@zack_falcon:它不会把VS2005搞砸,但你必须升级到VS2008。你可以从MSDN下载微软.NETFramework3.5SP1。这就是我害怕的。你会推荐什么其他的收集课程?我可以想出一个For-Loop解决方案,但它可能没有效率。
Dictonary<string, int> counts = new Dictionary<string, int>();
foreach(string value in list)
{
  if(counts.ContainsKey(value))
    counts[value]++;
  else
    counts[value] = 1;
}
foreach(KeyValuePair<string, int> kvp in counts)
  System.Diagnostics.Debug.WriteLine("\"{0}\" occurs {1} time(s).", kvp.Key, kvp.Value));