Fastest way to find common items across multiple lists in C#

后端 未结 11 1831

Given the following:

List> optionLists;

what would be a quick way to determine the subset of Option objects that a

11条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-19 02:48

    Here's a much more efficent implementation:

    static SortedDictionary.KeyCollection FindCommon (List> items)
    {
      SortedDictionary
        current_common = new SortedDictionary (),
        common = new SortedDictionary ();
    
      foreach (List list in items)
      {
        if (current_common.Count == 0)
        {
          foreach (T item in list)
          {
            common [item] = true;
          }
        }
        else
        {
          foreach (T item in list)
          {
            if (current_common.ContainsKey(item))
              common[item] = true;
            else
              common[item] = false;
          }
        }
    
        if (common.Count == 0)
        {
          current_common.Clear ();
          break;
        }
    
        SortedDictionary
          swap = current_common;
    
        current_common = common;
        common = swap;
        common.Clear ();
      }
    
      return current_common.Keys;
    }    
    

    It works by creating a set of all items common to all lists processed so far and comparing each list with this set, creating a temporary set of the items common to the current list and the list of common items so far. Effectively an O(n.m) where n is the number of lists and m the number of items in the lists.

    An example of using it:

    static void Main (string [] args)
    {
      Random
        random = new Random();
    
      List>
        items = new List>();
    
      for (int i = 0 ; i < 10 ; ++i)
      {
        List
          list = new List ();
    
        items.Add (list);
    
        for (int j = 0 ; j < 100 ; ++j)
        {
          list.Add (random.Next (70));
        }
      }
    
      SortedDictionary.KeyCollection
        common = FindCommon (items);
    
      foreach (List list in items)
      {
        list.Sort ();
      }
    
      for (int i = 0 ; i < 100 ; ++i)
      {
        for (int j = 0 ; j < 10 ; ++j)
        {
          System.Diagnostics.Trace.Write (String.Format ("{0,-4:D} ", items [j] [i]));
        }
    
        System.Diagnostics.Trace.WriteLine ("");
      }
    
      foreach (int item in common)
      {
        System.Diagnostics.Trace.WriteLine (String.Format ("{0,-4:D} ", item));
      }
    }
    

提交回复
热议问题