How to compress and decompress repeated string characters by storing the repeated length (RLE) in Swift

1 Answer

0 votes
import Foundation

/* ---------------------------------------------------------
   Compress: turn "aaabbcccc" into "a3b2c4"
   This is run-length encoding (RLE)
   --------------------------------------------------------- */
func compress(_ s: String) -> String {
    if s.isEmpty {
        return ""   // Edge case: empty string
    }

    var out = ""                // Result string
    var count = 1               // Count of repeated characters
    let chars = Array(s)

    // Start from index 1 and compare with previous character
    for i in 1...chars.count {

        // If still repeating the same character, increase count
        if i < chars.count && chars[i] == chars[i - 1] {
            count += 1
        } else {
            // Character changed OR reached end of string
            out.append(chars[i - 1])          // Add the character
            out.append(String(count))         // Add how many times it repeated
            count = 1                         // Reset counter
        }
    }

    return out
}


/* ---------------------------------------------------------
   Decompress: turn "a3b2c4" into "aaabbcccc"
   Reads a letter, then reads digits, expands them.
   --------------------------------------------------------- */
func decompress(_ s: String) -> String {
    var out = ""                 // Result string
    var currentChar: Character?  // The character being processed
    var number = ""              // Digits representing the count

    for c in s {

        if c.isLetter {          // Found a letter
            // If we already have a previous letter + number, expand it
            if let ch = currentChar, !number.isEmpty {
                if let count = Int(number) {
                    out.append(String(repeating: String(ch), count: count))
                }
            }

            currentChar = c      // Start new character
            number = ""          // Reset number buffer

        } else if c.isNumber {   // Found a digit
            number.append(c)     // Build multi-digit number
        }
    }

    // Handle the last character + number pair
    if let ch = currentChar, !number.isEmpty {
        if let count = Int(number) {
            out.append(String(repeating: String(ch), count: count))
        }
    }

    return out
}


func main() {
    let s = "wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww"

    let c = compress(s)
    let d = decompress(c)

    print("Original:    \(s)")
    print("Compressed:  \(c)")
    print("Decompressed: \(d)")
}

main()



/*
run:

Original:    wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
Compressed:  w12b1w10b3w6c4w12
Decompressed: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww

*/

 



answered 1 day ago by avibootz

Related questions

...