Wednesday, April 15, 2015

Overview

This is a similar post to my JavaToRemember post but for C#.

Table of content

  1. String
  2. Linked List
  3. Tree
  4. Graph
  5. Sorting
  6. Bit Manipulation
  7. Combinations and Permutations
  8. Files
  9. Regex
  10. Dictionary
  11. HashSet
  12. List
  13. Stack
  14. Queue
  15. Random




1. String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
"Hello".ToCharArray()             // ['H', 'e', 'l', 'l', 'o']
lst.Sort()                        // sorts a List in place
Array.Sort<char>(array);          // sort an array
list.Reverse();                   // reverses a List in place

string.Join("", char[] a)         // convert char[] to string
"Hello"[int x]                    // get a char at the specific index
"Hello".Length                    // string length
new int[]{1,2,3,4,5}.Length       // array's size (not how to initialize array)
list.Count                        // List's size

Char.IsLetter('a')                // true
Char.IsDigit(5)                   // true
Char.IsLetterOrDigit('a')         // true
Char.IsWhiteSpace(' ')            // true

Char.ToLower('A')                 // 'a'
Char.IsUpper('a')                 // false

Convert.ToString(23, 2)           // "10111"

// Substring(int position, int length)
"abcdef".Substring(1, 1)          // "b"
"abcdef".Substring(1, 4)          // "bcde"
"abcdef".Substring(3)             // "def"




2. Linked List

The node class which is the “element” of a linked list

1
2
3
4
5
6
7
8
9
public class Node {
  public int val;
  public Node next;
  
  public Node(int x) {
    val = x;      //value
    next = null;  //next element
  }
}

Stack implementation using the Linked List data structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Stack{
  public Node top; 
  

  /**
   *  Method that returns top node
   *  without removing it
   */
  public Node Peek(){
    if(top != null){
      return new Node(top.value);
    }
    return null;
  }
  
  /**
   *  Method used to remove and
   *  return top node
   */
  public Node Pop(){
    if(top == null){
      return null;
    } else {
      Node temp = top;
      top = top.next;
      return temp;  
    }
  }
  
  /** 
   *  Method to add Node
   *  to the top of the Stack
   */
  public void Push(Node n){
    if(n != null){
      n.next = top;
      top = n;
    }
  }
}

Queue implementation using the Linked List data structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Queue {
  public Node first;
  public Node last;
  
  /**
   *  Push an element to the back
   *  of the queue
   */
  public void Enqueue(Node n){
    if(first == null){
      first = n;
      last = first;
    } else {
      last.next = n;
      last = n;
    }
  }
 
  /**
   *  Remove element at the front
   */
  public Node Dequeue(){
    if(first == null){
      return null;
    } else {
      Node temp = first;
      first = first.next;
      if (first == null) {
          tail = null;
      }
      return temp;
    } 
  }
}




3. Tree

The tree class here is for the binary tree

1
2
3
4
5
6
class TreeNode {
  int value;
  TreeNode parent;
  TreeNode left;
  TreeNode right;
}
  1. Binary Search Tree: for all nodes, left children <= current node <= right children
  2. Balanced vs. Unbalanced: In a balanced tree, the depth of the sibling tree’s can differ max by 1
  3. Full Binary Tree: every node other than the leaves has two children.
  4. Perfect Binary Tree: a full binary tree + all leaves same depth + parents have 2 children
  5. Complete Binary Tree: a binary tree with only last lvl possibly incomplete. We add to lowest lvl and right most




4. Graph

Graphs are used for many things, such as Networking and games.The 2 most famous algorithms for graphs are Depth First Search and Breath First Search

GraphNode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class GraphNode{ 
  int val;
  GraphNode next;
  GraphNode[] neighbors;
  boolean visited;
 
  /**
   *  Constructor with value
   */
  GraphNode(int x) {
    val = x;
  }
  
  /**
   *  Constructor with value
   *  and with neightbors
   */
  GraphNode(int x, GraphNode[] n){
    val = x;
    neighbors = n;
  }
 
  /**
   *  ToString method
   */
  public override string ToString(){
    return "value: "+ this.val; 
  }
}

Breath First Search (live implementation from MIT here)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static Node bfs(Node root, int value) {
  Queue<Node> q = new Queue<Node>();
  Node returnValue;
  q.Enqueue(root);
  
  while (q.Length > 0) {
    Node temp = q.Dequeue();
    if (temp.value == value) {
      returnValue = temp;
      break;
    }
    foreach (Node adj in temp.adjecent) {
      q.Enqueue(adj);
    }
  }
  return returnValue;
}

Depth First Search (live implementation from MIT here)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static Node dfs(Node root, int value) {
  Stack<Node> s = new Stack<Node>();
  Node returnValue;
  s.Push(root);
  
  while (q.Length > 0) {
    Node temp = s.Pop();
    if (temp.value == value) {
      returnValue = temp;
      break;
    }
    foreach (Node adj in temp.adjecent) {
      s.Push(adj);
    }
  }
  return returnValue;
}




5. Sorting

Here is a table of comparison sorting algorithms and their time complexity

Algorithm Average Time Worst Time Space Comments
Bubble sort n^2 n^2 1 It’s easy to implement
Insertion sort n^2 n^2    
Selection sort n^2 n^2    
Heap sort nlogn nlogn    
Merge sort nlogn nlogn a lot  
Quick sort nlogn n^2   In practice, is fastest

Here is a table of algorithms that do not use comparison

Algorithm Average Time Worst Time Space Comments
Bucket sort n n + N   n is the range of keys, N is size of array
Radix sort n m(n + N)   m is the number of keys




6. Bit Manipulation

Bit operators

Operation name C# symbol Example Result Explanation
AND & 7 & 5 5 111 & 101 = 101
OR | 8 | 3 11 1000 | 0011 = 1011
XOR ^ 15 ^ 5 10 1111 ^ 0101 = 1010
Right Shift » 7 » 1 3 111 » 1 = 011
Not ~ ~0 -1 ~000 = 111 which is 2’s complement -1




7. Combinations and Permutations

  1. If the order doesn’t matter, it is a Combination… 1234 same as 4321
  2. If the order matters, it is a Permutation… 1234 != 2134

Permutation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void Perm(int[] list, int pos){
  if (pos == list.Length)
  {
    Console.WriteLine( string.Join("", list));
  }
  else
  {
    for(int i=pos; i < list.Length; ++i){
      Swap(list, i, pos);
      Perm(list, pos + 1);
      Swap(list, i, pos);
    }
  }
}

public static void Swap<T>(T[] a, int i, int j)
{
    T t = a[i];
    a[i] = a[j];
    a[j] = t;
}




8. Files

Writing to a file.

1
2
3
4
5
6
7
8
//Append
using (StreamWriter w = File.AppendText(@"C:\path\to\myText.txt"))
{
  w.WriteLine("hello");
}

string[] lines = { "First line", "Second line", "Third line" };
File.WriteAllLines(@"C:\Users\Public\TestFolder\WriteLines.txt", lines);

Reading from a file

1
2
//read all the lines in a file
string[] lines = File.ReadAllLines("path/to/myText.txt");




9. Regex

The full documentation can be found here Docs

1
2
3
4
5
6
7
8
string pattern = "a*b";

//Replace
Regex.Replace("gaaaabcde", pattern, String.Empty); // gcde

foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("{0} (duplicates '{1}') at position {2}", 
                           match.Value, match.Groups[1].Value, match.Index);




10. Dictionary

Dictionaries allow inserts, deletes and gets at O(1).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// var table = new Dictionary<string, int>{ {"a",1}, {"b",2}, {"c",3}};
Dictionary<string, int> dict = new Dictionary<string, int>();
dict["a"] = 1;    // { a:1 }
dict["b"] = 2;    // { a:1, b:2 }
dict["c"] = 3;    // { a:1, b:2, c:3 }

// to go over keys or values, we first cache them in a List then
// we can go over them and modify them. If we simply iterate over
// myDictionary.Keys, we can't modify the dictionary

// ["a", "b", "c"]
List<string> keys = myDictionary.Keys;
foreach(var key in keys) {
    // do stuff with key
}

// [1, 2, 3]
List<int> values =  myDictionary.Values;
foreach(var value in values) {
  // do stuff with value
}

// KeyValuePair<string, int> item
foreach(var pair in myDictionary) {
  // do stuff with pair.Key
  // do stuff with pair.Value
}

int value;
dict.TryGetValue("a", out value);   // value = 1
dict.ContainsKey("d");              // false
dict.Remove("a");                   // { b:2, c:3 }
dict.Clear();                       // {}




11. HashSet

A HashSet is a dictionary that only stores keys. It doesn’t allow for duplicates and only stores keys.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// var nums = new HashSet<int>{1, 2, 3};
HashSet<int> nums = new HashSet<int>();
nums.Add(1);       // { 1 }
nums.Add(2);       // { 1, 2 }
nums.Add(3);       // { 1, 2, 3 }

nums.Contains(5);  // false
nums.Contains(2);  // true
nums.Remove(2);    // { 1, 3 }

foreach(int val in nums) {
    Console.WriteLine("{0} ", val);
}
// 1
// 3

nums.RemoveWhere(s => s % 2 == 1); // remove odd

int[] array = nums.ToArray();   // [1,3]
List<int> list = hset.ToList(); // [1,3]

set.Clear();                    // {}




12. List

The List is a very widely used datastructure in C#. It can insert, add, remove, binary search etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// var lst = new List<int>{1, 2, 3, 4, 5};
List<int> lst = new List<int>();
lst.Add(1);       // [1]
lst.Add(2);       // [1, 2]
lst.Add(3);       // [1, 2, 3]
lst.Add(4);       // [1, 2, 3, 4]
lst.Add(5);       // [1, 2, 3, 4, 5]

lst.AddRange(new int[]{-1});
// [1, 2, 3, 4, 5, -1, -2]

lst.Insert(0, 9); // [9, 1, 2, 3, 4, 5, -1]
lst.InsertRange(0, new int[]{7, 9}); // [7, 8, 9, 1, 2, 3, 4, 5, -1]

lst.RemoveAt(lst.Count-1);    // [7, 8, 9, 1, 2, 3, 4, 5]
lst.RemoveRange(0, 3);        // [1, 2, 3, 4, 5]
// RemoveRange(int index, int count)

lst.Reverse();                // [5, 4, 3, 2, 1]
lst.Sort();                   // [1, 2, 3, 4, 5]

int idx = lst.BinarySearch(6);// -6
if (idx < 0)                  // ~(-6) = 5 the location to insert
  lst.Insert(~idx, 6);        // [1, 2, 3, 4, 5, 6]

List<string> lst2 = new List<string>{"Gab", "Vush", "Daisy", "Honey"};
lst2 = lst2.OrderBy( x => x.Length).Reverse().ToList();
// ["Honey", "Daisy", "Vush", "Gab"]

int[] array = lst.ToArray();  // [1, 2, 3, 4, 5, 6]
Dictionary<int,int> dict = lst.ToDictionary(item => item, item => 0);
// { 1:0, 2:0, 3:0, 4:0, 5:0, 6:0 }

// Enumerable.Range(int start, int count)
foreach(var i in Enumerable.Range(0, lst.Count)) {
    // i is the index
}




13. Stack

A stack is a FILO (first in, last out) data structure. You add to the back and remove from the back.

1
2
3
4
5
6
7
8
9
10
11
12
Stack<Tuple<string,int>> s = new Stack<Tuple<string,int>>();
s.Push(Tuple.Create("One",1));    // [("One",1)]
s.Push(Tuple.Create("Two", 2));   // [("One",1), ("Two",2)]
s.Push(Tuple.Create("Three", 3)); // [("One",1), ("Two",2), ("Three",3)]

var t = s.Pop();        // ("Three",3) s = [("One",1), ("Two",2)]
s.Peek();               // ("Two",2)   s = [("One",1), ("Two",2)]

s.Count                 // 2

t.Item1                 // "Three"
t.Item2                 // 3




14. Queue

A queue is a FIFO (first in, first out) data structure. You add to the back and remove from the front.

1
2
3
4
5
6
7
8
9
Queue<double> q = new Queue<double>();
q.Enqueue(1.1);       // [1.1]
q.Enqueue(2.2);       // [1.1, 2.2]
q.Enqueue(3.3);       // [1.1, 2.2, 3.3]

q.Dequeue();          // 1.1   q = [2.2, 3.3]
q.Peek();             // 2.2   q = [2.2, 3.3]

q.Count               // 2




15. Random

1
2
3
4
5
Random r = new Random();
r.Next();           // non negative random number
r.Next(5);          // [0, 5[
r.Next(0, 10);      // [0, 10[
r.NextDouble();     // [0.0, 1.0[

Random Posts