Swift Loops, Strings, and Characters: Tips and Tricks
Classified in Computers
Written on in English with a size of 6.55 KB
Loops
- // Loop forward
- for i in 0..
- // do something
- }
- // Loop in reverse
- for index in stride(from: 5, through: 1, by: -1) {
- print(index) // 5,4,3,2,1
- }
- // OR
- for i in (0..<10).reversed() {
- print(i)
- }
Strings
- // Convert String to Array of Strings containing 1 Character
- var strArr = str.characters.map { String($0) }
- // Join Array of Strings into 1 String
- var str = strArr.joined(separator: "")
- // Split String into array
- import Foundation
- let fullNameArr = fullName.components(separatedBy: " ")
- // Split String into Characters
- let subsequences = str.characters.split(separator: " ") // Returns array of Subsequence, not array of strings
- String(subsequences[0]) // to use as string
- // Convert String to Array of Characters
- sChars = Array(string.characters)
String/Character to Int
- // Convert Character to Int value (ASCII or unicode value)
- for char in string.unicodeScalars {
- print(char.value)
- }
- // Get Int value (unicode point) of a Character from a String
- extension Character {
- var unicodeValue: UInt32 {
- return String(self).unicodeScalars.first!.value
- }
- // OR
- var charValue: UInt16 {
- return (String(self) as NSString).character(at: 0)
- }
String Index
- // Need to have String.Index to access individual characters in a String
- str.startIndex // Index corresponding to 0
- str.endIndex // Index corresponding to N-1
- // Advance 5 from the start
- let s = "abcdef"
- let idx = s.index(s.startIndex, offsetBy: 5)
- s[idx] // → "f" (the Character, not the String)
- // From the back
- let s = "abcdef"
- let rIdx = s.index(s.endIndex, offsetBy: -1)
- s[rIdx] // → "f" (the Character, not the String) // Note, endIndex is not valid subscript
- let rIdx2 = s.index(rIdx, offsetBy: -1)
- s[rIdx2] // → "e" (the Character, not the String)
- // Safe index
- let safeIdx = s.index(s.startIndex, offsetBy: 400, limitedBy: s.endIndex)
- safeIdx // → nil
- // String slicing using Index
- s[s.startIndex..
Array
- // Slice Array
- Array(numbers[0..
- Array(numbers[0...2])
- // Elements dropping
- var a = [1,2,3] // Note: does not modify original array, returns array slice
- var b = Array(a.dropFirst()) // Works even if a is empty
- a.dropFirst(5) // Works even if greater than length of a
- a.dropLast()
- a.dropLast(4)
Character
- // Check if Char is alphanumeric lower case
- extension Character {
- var isAlphanumeric: Bool {
- return (self >= "a" && self <= "z") || (self >= "0" && self <= "9") // Add "A" and "Z" if needed
- }
Numbers
- // Absolute value
- abs(num) // If Int, returns Int too, if Double, returns Double
- // Infinity and NAN, only for Float, CGFloat, and Double, not for Int
- Double.infinity, Double.nan, -Double.infinity (negative infinity)
- someDouble.isFinite
- someDouble.isInfinite
- someDouble < Double.infinity
- someDouble = Double.greatestFiniteMagnitude
- someDouble.isInfinite // false
Misc Functions
- // Swap
- var b = [1,2,3,4,5]
- (b[0], b[1]) = (b[1], b[0])
- swap(&b[0], &b[1]) // This returns an error if same address [e.g. same index], so do not use!
- // Generate random
- var k: Int = random() % 10 // 0 - 9
- // Inout
- func swap(wordArr: inout Array, i: Int, j: Int) {
- // Modify wordArr, the original array passed will also be modified on return of this function (copy-in copy-out)
- }
- // Reserve capacity in Arrays / Dictionary to avoid overhead of resizing
- var longestSubstring = [Character: Int](minimumCapacity: 256)
- var dict = [Int:Int]()
- dict.reserveCapacity(256)
Big O
- 1
- log N
- N
- N log N
- N^2
- 2^N
- N!
- // Big O Other Notes
- // 1. Doubling
- 1+2+4+8+16+...N
- -> almost 2N (exactly 2N-1)
- This can also be seen as
- 2^0 + 2^1 + 2^2 + ... 2^N
- -> 2^(N+1) - 1 (still same as above, because N = this 2^N)
- // 2. Halving (this is same as above, but treated looked at different perspective
- N + (N/2) + (N/4) + (N/8) + ... + 1
- -> almost 2N
- if N not included
- (N/2) + (N/4) + (N/8) + ... + 1
- -> almost N
- // 3. Sequence
- 1+2+3+4+5+...N
- -> (N(N+1)) / 2
- // 4. Recursion
- branches ^ depth
- e.g. if two branches like fibonacci - 2^N, where N is depth
- // 5. Nested loops, such that 2nd loop decreases by one
- e.g. 5+4+3+2+1 for each loop
- so (N(N+1)) / 2 -> O(N^2)
- // 6. Loop, such that i value decreases or advances by twice
- log N
Bits
- // 1. Determine if power of 2:
- N & (N-1) == 0
- // 2. Determine lowest power of 2 near N:
- N & (N-1) // Repeat until 0, the times you did this is the power of 2
- // 3. Determine unique value from 3 pairs of INT where 2 are equal
- X1 XOR X2 XOR X3 = answer
- // 4. Swap two numbers without using additonal space
- x = x XOR Y
- y = x XOR Y
- x = x XOR y
- // 5. To multiply by two, shift left 1 time
- // To multiply by power of two, shift left power of two times
Heap Formulas
- A heap with n nodes has height h = floor(log_2(n))
- If the lowest level is completely full, then that level contains 2^h nodes.
- The rest of the tree above it contains 2^h - 1nodes.
- *The leaf nodes are always located at array indices floor(n/2) to n-1, where n = number of nodes
- *To create heap from array, you can start from:
- (n/2) - 1, up to 0
- since (n/2) up to (n-1) are the leaf nodes, so no need to process them
- * Number of leaf nodes of a complete binary tree (e.g. heap)
- = ceil ( n/2 )
Misc Notes
- // When computing mid for binary search / merge sort, use the following code in order to avoid Int Overflow
- let mid = left + ((right - left) / 2)
- // Reallocation factor in Swift
- array: 2
- string: 2
- dict: 1.333