Saturday, July 31, 2010

Shell Script to Check Whether a String is Palindrome or not


Palindrome: A palindrome is a word, phrase, number or other sequence
of units that can be read the same way in either direction (the adjus-
tment of punctuation and spaces between words is generally permitted).

Examples:

Phrases: Dammit, I'm mad!
Quotations: Able was I ere I saw Elba.
Madam, I'm Adam.
Names: Some people have names that are palindromes.Lon Nol (1913-
1985) was Prime Minister of Cambodia.
Palindromic names are very common in Finland. Examples
include Emma Lamme,Sanna Rannas, Anni Linna and Asko Oksa.
Words: civic,radar,level,rotator,rececar,reviver.
The command "Level, madam, level!", composed only of words
that are themselves palindromes, is both a character-by-
character and a word-by-word palindrome.
Numbers: 5335, 123454321
Dates: 01/02/2010 (dd/mm/yyyy format)

Method 1:


#!/bin/bash
# SCRIPT: palindrome1.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# In this script I uses the well known method, compare first character
# with last character, up to middle of the string. One mismatch in the
# scanning leads to immediate termination of the scanning as it is
# not a palindrome. To extract character from string, I will use cut
# command with the -c option with the position number.
#
#####################################################################
# Arguments Checking #
#####################################################################

if [ $# -eq 0 ]
then
echo -n "Enter a String: "
read orgstr
else
orgstr=$*
fi

# You can also use single statement
#[ $# -eq 0 ] && (echo -n "Enter a String:"; read String) || String=$*

#####################################################################
# Variable Initialization #
#####################################################################

# Remove all punctuations from input string and convert upper case to
# lower or lower case to upper.

String="$(echo $orgstr | sed 's/[^[:alnum:]]//g' | \
tr '[:upper:]' '[:lower:]')"

Flag=0

# Find length of the string.
len=${#String}

#You can also calculate string length using bellow commands.
#len=`echo $str | wc -c`
#len=$((len-1))

#get the mid value up to which the comparison would be done.
mid=$((len/2))

#####################################################################
# Main Script Starts Here #
#####################################################################

for ((i=1;i<=mid;i++))
do
c1=`echo $String|cut -c$i` # extracts from beginning
c2=`echo $String|cut -c$len` # extracts from last

if [ $c1 != $c2 ]
then
Flag=1


break 2 # break N breaks out of N levels of loop.
fi

let len--
done

if [ $Flag -eq 0 ]
then
echo "\"$orgstr\" is a Palindrome"
else
echo "\"$orgstr\" is not a Palindrome"
fi


OUTPUT:

[root@www ]# ./palindrome1.sh Dammit, I\'m mad!
"Dammit, I'm mad!" is a Palindrome
[root@www ]# ./palindrome1.sh
Enter a String: 01/02/2010
"01/02/2010" is a Palindrome
[root@www ]# ./palindrome1.sh Hello world
"Hello world" is not a Palindrome


Method 2:


#!/bin/bash
# SCRIPT: palindrome2.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# In this script I uses the well known method, compare first character
# with last character, up to middle of the string. One mismatch in the
# scanning leads to immediate termination of the scanning as it is
# not a palindrome. To extract a character from the string, I will use
# string manipulation operations.So you need to know how to manipulate
# strings to understand this script. I will give little bit of explan-
# tion at the end of this script.
#
#####################################################################
# Arguments Checking #
#####################################################################

[ $# -eq 0 ] && { echo -n "Enter a String: "; read orgstr ;} || \
orgstr=$*

#####################################################################
# Variable Initialization #
#####################################################################

# Remove all punctuations from input string and convert upper case to
# lower or lower case to upper.

String="$(echo $orgstr | sed 's/[^[:alnum:]]//g' | \
tr '[:upper:]' '[:lower:]')"

# Find length of the string.
len=${#String}

#get the mid value up to which the comparison would be done
mid=$(($len/2))

i=0
Flag=0

#####################################################################
# Main Script Starts Here #
#####################################################################

while [ $i -lt $mid ]
do
fchar=${String:$i:1}
let i++
bchar=${String: -$i:1}
if [ "$fchar" != $bchar ]
then
Flag=1
break 2 # break N breaks out of N levels of loop.
fi
done

if [ $Flag -eq 0 ]
then
echo "\"$orgstr\" is a Palindrome"
else
echo "\"$orgstr\" is not a Palindrome"
fi


Substring Extraction:

${string:position}
Extracts substring from $string at $position.
${string:position:length}
Extracts $length characters of substring from $string at $position

Bash numbers first character of string as '0'.

${string: 0: 1} will extracts one character from the 0th character of
the string, ie it will only get the 0th character. ${string: 2: 1}
will get the third character. Also ${string: -1: 1} will extracts the
last one character, ${string: -3:1} will get the third last character.

Note: ${string: -1:1} in this construct don't forget to give space
before -1, otherwise you will get full string.

For example

[root@localhost www]# tempvar=madam
[root@localhost www]# echo ${tempvar: -1:1}
m
[root@localhost www]# echo ${tempvar:-1:1}
madam

You can also use following command

[root@localhost www]# echo ${tempvar:(-1):1}
m

OUTPUT:

[root@www ]# ./palindrome2.sh Able was I ere I saw Elba
"Able was I ere I saw Elba" is a Palindrome
[root@www ]# ./palindrome2.sh 123454321
"123454321" is a Palindrome
[root@www ]# ./palindrome2.sh
Enter a String: 12345654321
"12345654321" is a Palindrome
[root@www ]# ./palindrome2.sh
Enter a String: 1234564321
"1234564321" is not a Palindrome


Method 3:


#!/bin/bash
# SCRIPT: palindrome3.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# This simply uses the 'rev' utility which is used to reverse lines of
# a file. Then check if the reverse of the string is same as the
# original.rev command is part of util-linux-ng or util-linux package.
#

if `which rev &>/dev/null` # Checks rev command exist or not
then
[ $# -eq 0 ] && { echo -n "Enter a String: "; read orgstr ;} || \
orgstr=$*

String="$(echo $orgstr | sed 's/[^[:alnum:]]//g' | \
tr '[:upper:]' '[:lower:]')"

if [ "$(echo $String | rev)" = "$String" ]
then
echo "\"$orgstr\" is a palindrome"
else
echo "\"$orgstr\" is not a palindrome"
fi

else
echo "Install util-linux or util-linux-ng package"
fi


OUTPUT:

[root@www ]# ./palindrome3.sh 01/02/2010
"01/02/2010" is a palindrome
[root@www ]# ./palindrome3.sh 01/03/2010
"01/03/2010" is not a palindrome
[root@www ]# ./palindrome3.sh
Enter a String: Hello World
"Hello World" is not a palindrome
[root@www ]# ./palindrome3.sh
Enter a String: rotator
"rotator" is a palindrome


Method 4:


#!/bin/bash
# SCRIPT: palindrome4.sh
# USAGE: palindrome.sh or palindrome.sh STRING
# PURPOSE: Script to test if a given string is a palindrome.
#
# In this method we are not using 'rev' command to reverse the string.
# Using Substring Removal method or Substring Extraction method we
# will reverse the string, then compare it with oldstring.
#
#####################################################################
# Arguments Checking #
#####################################################################

[ $# -eq 0 ] && { echo -n "Enter a String: "; read orgstr ;} || \
orgstr=$*

#####################################################################
# Variable Initialization #
#####################################################################

String="$(echo $orgstr | sed 's/[^[:alnum:]]//g' | \
tr '[:upper:]' '[:lower:]')"

oldstring=$String
newstring=

#####################################################################
# Main Script Starts Here #
#####################################################################

while [ -n "$String" ]
do
temp=${String#?}
letter=${String%"$temp"}
String=$temp
newstring=${letter}${newstring}
done

if [ "$oldstring" = "$newstring" ]
then
echo "\"$orgstr\" is a palindrome"
else
echo "\"$orgstr\" is not a palindrome"
fi

# ${string#substring} is a Substing Removal operation. If you want to
# use Substring Extraction method, use bellow code.

#i=0
#while [ $i -lt ${#String} ]
#do
# letter=${String:$i:1}
# newstring=${letter}${newstring}
# let i++;
#done
#
#if [ "$String" = "$newstring" ]
#then
# echo "\"$orgstr\" is a palindrome"
#else
# echo "\"$orgstr\" is not a palindrome"
#fi


Substring Removal:

${string#substring}
Strips shortest match of $substring from front of $string.

Example:

[root@www]# tempvar=madam
[root@www]# echo ${tempvar#m}
adam
[root@www]# echo ${tempvar#ma}
dam
[root@www]# echo ${tempvar#?}
adam


${string%substring}
Strips shortest match of $substring from back of $string.

Example:

[root@www]# temp=${tempvar#?}
[root@www]# echo $temp
adam
[root@www]# echo ${tempvar%$temp}
m

OUTPUT:

[root@www ]# ./palindrome4.sh Madam, I\'m Adam
"Madam, I'm Adam" is a palindrome
[root@www ]# ./palindrome4.sh Madam I Adam
"Madam I Adam" is not a palindrome
[root@www ]# ./palindrome4.sh
Enter a String: 123454321
"123454321" is a palindrome
[root@www ]# ./palindrome4.sh
Enter a String: 1234564321
"1234564321" is not a palindrome

3 comments:

  1. i found your posts on palindromes using bash helpful. thanks.

    ReplyDelete
  2. Hey, thanks for this program! I found it useful.

    ReplyDelete
  3. I am learning shell scripting so it is very helpful to me.
    Thanks

    ReplyDelete