c# - Improving performance of Dictionary using Arrays -


consider counting number of occurrences of particular letter in word.

i came solution.

string = "aabbcdc"; //output: a:2,b:2,c:2,d:1 var dict = new dictionary<char, int>(); foreach(var @char in a) {   if(dict.containskey(@char))      dict[@char] = dict[@char] + 1;    else dict.add(@char, 1); } foreach(var keyvaluepair in dict)   console.writeline("letter = {0}, value = {1}", keyvaluepair.key, keyvaluepair.value); 

my friend argued solution can improved further using arrays better using above dictionary.

i guess, dictionary lookup o(1) (arrays o(1), correct ?) . ideas how re-write program using arrays performs better?

arrays o(1), correct

arrays o(1) when accessing known offset. o(n) when have scan array find particular match.

you not out-perform dictionary type of operation in general case.

you can leverage accessing known offset caveat use arrays limited case. example, if know have input in range 'a'..'z', can have array of counts

int[] counts = new int[26];  // initialize array elements 0 first. count[(int)(ch - 'a')]++; 

this type of code fragile in change range of input values breaks it. performance gain not matter vs. dictionary cases. if think case needs small performance edge, benchmark before using more fragile implementation arrays.

this type of operation pretty common. wrote generic class it

[serializable] public class occurrencecounter<t> {     private dictionary<t, int> counts;      public occurrencecounter()     {         initialize(default(streamingcontext));     }      [ondeserialized]     public void initialize(streamingcontext context)     {         if (counts == null)         {             counts = new dictionary<t, int>();             counts.ondeserialization(this);         }     }      public int this[t key]     {                  {             if (counts.containskey(key))             {                 return counts[key];             }             else return 0;         }     }      public bool containskey(t key)     {         return counts.containskey(key);     }      public int total()     {         return counts.sum(c => c.value);     }      public int count()     {         return counts.count;     }      public int totalfor(ienumerable<t> keys)     {         if (keys == null) throw new argumentexception("parameter keys must not null.");          hashset<t> hash = keys.tohashset();         return counts.where(k => hash.contains(k.key)).sum(k => k.value);     }       public void increment(t key, int amount = 1)     {         if (!counts.containskey(key))         {             counts.add(key, amount); // initialize 0 , increment         }         else         {             counts[key]+=amount;         }     }      public void decrement(t key, int amount = 1)     {         if (!counts.containskey(key))         {             counts.add(key, -amount); // initialize 0 , decrement         }         else         {             counts[key]-=amount;         }     }       /// <summary>     /// not correctly implement ienumerable on .net (seems compile on mono).  should fixed.     /// see: http://stackoverflow.com/questions/16270722/ienumerablet-int-arity-and-generic-type-definitions     /// </summary>     /// <returns></returns>     public ienumerable<keyvaluepair<t, int>> iterate()     {         foreach (keyvaluepair<t, int> kvp in counts) yield return kvp;     }  } 

Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -