0

Original Q. Given a string containing uppercase characters (A-Z), compress the string using Run Length encoding. Repetition of character has to be replaced by storing the length of that run. Write a unix function encode(message) which performs the run length encoding for a given String and returns the run length encoded String. Provide different String values and test your program. Example: message=AAAABBBBCCCCCCCC output: 4A4B8C

#!/usr/bin/bash

encode()
{
        msg=$1

        for (( i=0 ; i<${#msg} ; i++ ))
        do
                j=$(($i+1))
                if [[ $j < ${#msg} ]] && [[ ${msg:$i:1} == ${msg:$j:1} ]]
                then
                        echo "${msg:$i:1} == ${msg:$j:1}"
                else
                        echo "${msg:$i:1} != ${msg:$j:1}"
                fi
        done
}

#read -p "Enter String to Encrypt : " str
str='AAAABBBBCCCCCCCC'

if [ ${#str} -eq 0 ] || ! [[ $str =~ [a-zA-Z]+$ ]]
then
        echo -e "\n===> Invalid String <===\n"
        exit
fi

echo -e "Input  => $str"
encode $str

Getting OUTPUT :

[practiceScript]$ bash 20.sh
Input  => AAAABBBBCCCCCCCC
A == A
A != A
A != A
A != B
B != B
B != B
B != B
B != C
C != C
C == C
C == C
C == C
C == C
C == C
C == C
C !=
[practiceScript]$

Want to understand why my script is generating Not Equal Output for same character i

5
  • Change [[ $j < ${#msg} ]] to [[ $j -lt ${#msg} ]]. You're doing string comparison, not numeric comparison, and 2 < 16 is false. Commented Jul 29, 2022 at 20:03
  • Double bracket does not handle this operators internally? If not then what's the purpose of having double bracket and single bracket? Commented Jul 29, 2022 at 20:06
  • Also if it is because of incorrect operator then condition should fail for 1st comparison A=A and later multiple C=C comparisons as well. Commented Jul 29, 2022 at 20:09
  • Double bracket allows you to leave out the $ before variables, and it also doesn't do word splitting, so you don't have to quote variables. But it doesn't change the way the operators work. If you want an arithmetic expression, use (()): (( $j < ${#msg} )) Commented Jul 29, 2022 at 20:09
  • It works for the first one because 1 < 16 is true. Commented Jul 29, 2022 at 20:09

2 Answers 2

2

I suggest:

# Remove single newline from $1 at the end, append a newline after 
# every character, count characters and remove all newlines and spaces
encode() {
  echo "$1" | tr -d '\n' | sed "s/./&\n/g" | uniq -c | tr -d '\n '
}

message="AAAABBBBCCCCCCCC"
encode "$message"

Output:

4A4B8C
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot but I wish to create script without sed and awk
0

A method in pure bash to achieve this task:

#!/bin/bash

encode () {
    local msg=$1 prefix pat

    while [[ $msg ]]; do
        pat=[^${msg:0:1}]*
        prefix=${msg%%$pat}
        printf '%d%s' ${#prefix} "${prefix:0:1}"    
        msg=${msg#"$prefix"}
    done
    echo
}

encode AAAABBBBCCCCCCCC

2 Comments

code work fine but could you please explain prefix=${msg%%$pat}
@namz It's a type of parameter expansion. You may consider reading Shell Parameter Expansion, the paragraph starting with ${parameter%%word}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.