C# Dictionary and HashSet operations

Dictionary<TKey, TValue> stores key–value pairs with O(1) average lookup. TryGetValue reads a value and tells whether the key exists, in one lookup, so counting items is a loop of TryGetValue followed by an assignment. The indexer throws KeyNotFoundException for a missing key. Enumeration order is not something to rely on, so sort before printing.

C#
using System;
using System.Collections.Generic;
using System.Linq;

class Program {
  static void Main() {
    string text = "the quick brown fox jumps over the lazy dog the end";
    var counts = new Dictionary<string, int>();
    foreach (string word in text.Split(' ')) {
      counts[word] = counts.TryGetValue(word, out int seen) ? seen + 1 : 1;
    }
    foreach (var pair in counts.OrderByDescending(p => p.Value).ThenBy(p => p.Key).Take(3)) {
      Console.WriteLine(pair.Key + ": " + pair.Value);
    }
    Console.WriteLine("distinct words: " + counts.Count);

    var a = new HashSet<int> { 1, 2, 3, 4 };
    var b = new HashSet<int> { 3, 4, 5 };
    var inter = new HashSet<int>(a);
    inter.IntersectWith(b);
    var union = new HashSet<int>(a);
    union.UnionWith(b);
    var diff = new HashSet<int>(a);
    diff.ExceptWith(b);
    Console.WriteLine("intersection " + string.Join(" ", inter.OrderBy(x => x)));
    Console.WriteLine("union " + string.Join(" ", union.OrderBy(x => x)));
    Console.WriteLine("difference " + string.Join(" ", diff.OrderBy(x => x)));
  }
}
Read the full lesson