Overview
This is a similar post to my JavaToRemember post but for C#.
Table of content
- String
- Linked List
- Tree
- Graph
- Sorting
- Bit Manipulation
- Combinations and Permutations
- Files
- Regex
- Dictionary
- HashSet
- List
- Stack
- Queue
- 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;
}
- Binary Search Tree: for all nodes, left children <= current node <= right children
- Balanced vs. Unbalanced: In a balanced tree, the depth of the sibling tree’s can differ max by 1
- Full Binary Tree: every node other than the leaves has two children.
- Perfect Binary Tree: a full binary tree + all leaves same depth + parents have 2 children
- 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
- If the order doesn’t matter, it is a Combination… 1234 same as 4321
- 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[