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

1 Answer

0 votes
package main

import (
    "fmt"
    "strconv"
    "strings"
)

/* ---------------------------------------------------------
   Compress: turn "aaabbcccc" into "a3b2c4"
   This is run-length encoding (RLE)
   --------------------------------------------------------- */
func compress(s string) string {
    if len(s) == 0 {
        return "" // Edge case: empty string
    }

    var out strings.Builder // Result string
    count := 1              // Count of repeated characters

    // Start from index 1 and compare with previous character
    for i := 1; i <= len(s); i++ {

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

    return out.String()
}

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

    for i := 0; i < len(s); i++ {
        c := s[i]

        if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') { // Found a letter
            // If we already have a previous letter + number, expand it
            if currentChar != 0 && number.Len() > 0 {
                count, _ := strconv.Atoi(number.String())
                out.WriteString(strings.Repeat(string(currentChar), count))
            }

            currentChar = c // Start new character
            number.Reset()  // Reset number buffer

        } else if c >= '0' && c <= '9' { // Found a digit
            number.WriteByte(c) // Build multi-digit number
        }
    }

    // Handle the last character + number pair
    if currentChar != 0 && number.Len() > 0 {
        count, _ := strconv.Atoi(number.String())
        out.WriteString(strings.Repeat(string(currentChar), count))
    }

    return out.String()
}

func main() {
    s := "wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww"

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

    fmt.Println("Original:   ", s)
    fmt.Println("Compressed: ", c)
    fmt.Println("Decompressed:", d)
}



/*
run:

Original:    wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
Compressed:  w12b1w10b3w6c4w12
Decompressed: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww

*/

 



answered 1 day ago by avibootz

Related questions

...