Solutions to Basic Algorithms with SwiftUI

Solutions to Basic Algorithms with SwiftUI

In this article, we will explore the solutions to popular algorithms in Swift and how they can be visualized with SwiftUI.


1. Reverse a String

Algorithm

To reverse a string, we can convert the string into an array of characters and then reverse that array.

Code:

func reverseString(_ str: String) -> String {
    return String(str.reversed())
}        

Example Scenario:

let input = "Hello, World!"
let reversed = reverseString(input)  // "!dlroW ,olleH"        

SwiftUI Implementation:

struct ReverseStringView: View {
    @State private var inputString: String = ""
    @State private var reversedString: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string", text: $inputString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                self.reversedString = reverseString(self.inputString)
            }) {
                Text("Reverse String")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(reversedString)
                .padding()
        }
        .padding()
    }
}

func reverseString(_ str: String) -> String {
    return String(str.reversed())
}        

2. Check if a String is a Palindrome

Algorithm

A palindrome is a word, phrase, number, or other sequence of characters that reads the same forward and backward. We can check if a string is a palindrome by comparing it to its reverse.

Code:

func isPalindrome(_ str: String) -> Bool {
    return str == String(str.reversed())
}        

Example Scenario:

let word = "madam"
let result = isPalindrome(word)  // true        

SwiftUI Implementation:

struct PalindromeView: View {
    @State private var inputString: String = ""
    @State private var result: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string", text: $inputString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                self.result = isPalindrome(self.inputString) ? "Palindrome" : "Not a Palindrome"
            }) {
                Text("Check Palindrome")
                    .padding()
                    .background(Color.green)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(result)
                .padding()
        }
        .padding()
    }
}

func isPalindrome(_ str: String) -> Bool {
    return str == String(str.reversed())
}        

3. Remove Duplicates from a String

Algorithm

To remove duplicates from a string, we can use a set to track the characters we’ve seen.

Code:

func removeDuplicates(_ str: String) -> String {
    var seen = Set<Character>()
    var result = ""
    for char in str {
        if !seen.contains(char) {
            seen.insert(char)
            result.append(char)
        }
    }
    return result
}        

Example Scenario:

let input = "aabbcc"
let result = removeDuplicates(input)  // "abc"        

SwiftUI Implementation:

struct RemoveDuplicatesView: View {
    @State private var inputString: String = ""
    @State private var resultString: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string", text: $inputString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                self.resultString = removeDuplicates(self.inputString)
            }) {
                Text("Remove Duplicates")
                    .padding()
                    .background(Color.orange)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text("Result: \(resultString)")
                .padding()
        }
        .padding()
    }
}

func removeDuplicates(_ str: String) -> String {
    var seen = Set<Character>()
    var result = ""
    for char in str {
        if !seen.contains(char) {
            seen.insert(char)
            result.append(char)
        }
    }
    return result
}        

4. Find the First Non-Repeating Character

Algorithm

To find the first non-repeating character, we can keep track of character counts in a dictionary.

Code:

func firstNonRepeatingCharacter(_ str: String) -> Character? {
    var counts = [Character: Int]()
    for char in str {
        counts[char, default: 0] += 1
    }
    for char in str {
        if counts[char] == 1 {
            return char
        }
    }
    return nil
}        

Example Scenario:

let input = "swiss"
let result = firstNonRepeatingCharacter(input)  // "w"        

SwiftUI Implementation:

struct FirstNonRepeatingCharacterView: View {
    @State private var inputString: String = ""
    @State private var resultCharacter: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string", text: $inputString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                if let character = firstNonRepeatingCharacter(self.inputString) {
                    self.resultCharacter = "First Non-Repeating Character: \(character)"
                } else {
                    self.resultCharacter = "No non-repeating character."
                }
            }) {
                Text("Find First Non-Repeating Character")
                    .padding()
                    .background(Color.red)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(resultCharacter)
                .padding()
        }
        .padding()
    }
}

func firstNonRepeatingCharacter(_ str: String) -> Character? {
    var counts = [Character: Int]()
    for char in str {
        counts[char, default: 0] += 1
    }
    for char in str {
        if counts[char] == 1 {
            return char
        }
    }
    return nil
}        

5. Check if Two Strings are Anagrams

Algorithm

To check if two strings are anagrams, we can sort the characters of both strings and compare them.

Code:

func areAnagrams(_ str1: String, _ str2: String) -> Bool {
    return str1.sorted() == str2.sorted()
}        

Example Scenario:

let str1 = "listen"
let str2 = "silent"
let result = areAnagrams(str1, str2)  // true        

SwiftUI Implementation:

struct AnagramCheckView: View {
    @State private var string1: String = ""
    @State private var string2: String = ""
    @State private var result: String = ""

    var body: some View {
        VStack {
            TextField("Enter first string", text: $string1)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            TextField("Enter second string", text: $string2)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                self.result = areAnagrams(self.string1, self.string2) ? "Anagrams" : "Not Anagrams"
            }) {
                Text("Check Anagram")
                    .padding()
                    .background(Color.purple)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(result)
                .padding()
        }
        .padding()
    }
}

func areAnagrams(_ str1: String, _ str2: String) -> Bool {
    return str1.sorted() == str2.sorted()
}        

6. Find the Longest Substring Without Repeating Characters

Algorithm

To find the longest substring without repeating characters, we can use a sliding window technique.

Code:

func longestSubstringWithoutRepeating(_ str: String) -> String {
    var seen = Set<Character>()
    var start = 0
    var maxLength = 0
    var longestSubstring = ""

    for (end, char) in str.enumerated() {
        while seen.contains(char) {
            seen.remove(str[start])
            start += 1
        }
        seen.insert(char)
        let length = end - start + 1
        if length > maxLength {
            maxLength = length
            longestSubstring = String(str[start...end])
        }
    }
    return longestSubstring
}        

Example Scenario:

let input = "abcabcbb"
let result = longestSubstringWithoutRepeating(input)  // "abc"        

SwiftUI Implementation:

struct LongestSubstringView: View {
    @State private var inputString: String = ""
    @State private var longestSubstring: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string", text: $inputString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                self.longestSubstring = longestSubstringWithoutRepeating(self.inputString)
            }) {
                Text("Find Longest Substring")
                    .padding()
                    .background(Color.cyan)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text("Longest Substring: \(longestSubstring)")
                .padding()
        }
        .padding()
    }
}

func longestSubstringWithoutRepeating(_ str: String) -> String {
    var seen = Set<Character>()
    var start = 0
    var maxLength = 0
    var longestSubstring = ""

    for (end, char) in str.enumerated() {
        while seen.contains(char) {
            seen.remove(str[start])
            start += 1
        }
        seen.insert(char)
        let length = end - start + 1
        if length > maxLength {
            maxLength = length
            longestSubstring = String(str[start...end])
        }
    }
    return longestSubstring
}        

7. Reverse Integer

Algorithm

We can reverse an integer by converting it to a string, reversing the string, and then converting it back to an integer.

Code:

func reverseInteger(_ num: Int) -> Int? {
    let isNegative = num < 0
    var num = abs(num)
    var reversed = 0

    while num != 0 {
        let digit = num % 10
        reversed = reversed * 10 + digit
        num /= 10
    }

    return isNegative ? -reversed : reversed
}        

Example Scenario:

let number = 12345
let reversed = reverseInteger(number)  // 54321        

SwiftUI Implementation:

struct ReverseIntegerView: View {
    @State private var inputNumber: String = ""
    @State private var reversedNumber: String = ""

    var body: some View {
        VStack {
            TextField("Enter an integer", text: $inputNumber)
                .keyboardType(.numberPad)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                if let num = Int(self.inputNumber), let reversed = reverseInteger(num) {
                    self.reversedNumber = "Reversed: \(reversed)"
                } else {
                    self.reversedNumber = "Invalid input"
                }
            }) {
                Text("Reverse Integer")
                    .padding()
                    .background(Color.yellow)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(reversedNumber)
                .padding()
        }
        .padding()
    }
}

func reverseInteger(_ num: Int) -> Int? {
    let isNegative = num < 0
    var num = abs(num)
    var reversed = 0

    while num != 0 {
        let digit = num % 10
        reversed = reversed * 10 + digit
        num /= 10
    }

    return isNegative ? -reversed : reversed
}        

8. Find the Most Frequent Character in the String

Algorithm

We can track the frequency of characters using a dictionary and then find the character with the highest frequency.

Code:

func mostFrequentCharacter(_ str: String) -> Character? {
    var counts = [Character: Int]()
    for char in str {
        counts[char, default: 0] += 1
    }
    return counts.max(by: { $0.value < $1.value })?.key
}        

Example Scenario:

let str = "abacabad"
let mostFrequentChar = mostFrequentCharacter(str)  // "a"        

SwiftUI Implementation:

struct MostFrequentCharacterView: View {
    @State private var inputString: String = ""
    @State private var frequentCharacter: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string", text: $inputString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                if let character = mostFrequentCharacter(self.inputString) {
                    self.frequentCharacter = "Most frequent character: \(character)"
                } else {
                    self.frequentCharacter = "No characters found."
                }
            }) {
                Text("Find Most Frequent Character")
                    .padding()
                    .background(Color.teal)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(frequentCharacter)
                .padding()
        }
        .padding()
    }
}

func mostFrequentCharacter(_ str: String) -> Character? {
    var counts = [Character: Int]()
    for char in str {
        counts[char, default: 0] += 1
    }
    return counts.max(by: { $0.value < $1.value })?.key
}        

9. Generic Optional

Algorithm

In Swift, Optionals are used to represent values that may or may not be present. Using Generic types with Optionalmakes parameters nullable.

Code:

func unwrap<T>(_ value: T?) -> String {
    guard let value = value else {
        return "Value is nil"
    }
    return "Value is \(value)"
}        

Example Scenario:

let str: String? = "Hello"
let result = unwrap(str)  // "Value is Hello"

let num: Int? = nil
let result2 = unwrap(num)  // "Value is nil"        

SwiftUI Implementation:

struct GenericOptionalView: View {
    @State private var inputString: String? = nil
    @State private var result: String = ""

    var body: some View {
        VStack {
            TextField("Enter a string (optional)", text: Binding(
                get: { self.inputString ?? "" },
                set: { self.inputString = $0.isEmpty ? nil : $0 }
            ))
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()

            Button(action: {
                self.result = unwrap(self.inputString)
            }) {
                Text("Unwrap Optional")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text(result)
                .padding()
        }
        .padding()
    }
}

func unwrap<T>(_ value: T?) -> String {
    guard let value = value else {
        return "Value is nil"
    }
    return "Value is \(value)"
}        

10. Longest Common Prefix

Algorithm

To find the longest common prefix, we can compare the characters of the first word with the other words character by character.

Code:

func longestCommonPrefix(_ strs: [String]) -> String {
    guard !strs.isEmpty else { return "" }
    
    var prefix = strs[0]
    for str in strs.dropFirst() {
        while !str.hasPrefix(prefix) {
            prefix = String(prefix.dropLast())
            if prefix.isEmpty {
                return ""
            }
        }
    }
    return prefix
}        

Example Scenario:

let words = ["flower", "flow", "flight"]
let commonPrefix = longestCommonPrefix(words)  // "fl"        

SwiftUI Implementation:

struct LongestCommonPrefixView: View {
    @State private var inputStrings: String = ""
    @State private var commonPrefix: String = ""

    var body: some View {
        VStack {
            TextField("Enter words separated by commas", text: $inputStrings)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: {
                let words = inputStrings.split(separator: ",").map { String($0).trimmingCharacters(in: .whitespaces) }
                self.commonPrefix = longestCommonPrefix(words)
            }) {
                Text("Find Common Prefix")
                    .padding()
                    .background(Color.green)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }

            Text("Common Prefix: \(commonPrefix)")
                .padding()
        }
        .padding()
    }
}

func longestCommonPrefix(_ strs: [String]) -> String {
    guard !strs.isEmpty else { return "" }
    
    var prefix = strs[0]
    for str in strs.dropFirst() {
        while !str.hasPrefix(prefix) {
            prefix = String(prefix.dropLast())
            if prefix.isEmpty {
                return ""
            }
        }
    }
    return prefix
}        

Conclusion

In this article, we covered basic algorithms and how to implement them in Swift. For each algorithm, we also integrated a SwiftUI interface to make the solution interactive. These algorithms can be beneficial both for improving your programming skills and for building interactive applications in Swift.

要查看或添加评论,请登录

UFuk ?atalca的更多文章

社区洞察