Archive for October, 2008

Quick Sort in Java

This is an easy verion of the popular quick sort algorithm implemented in Java.  Since the main aim is to keep it simple, this does not use the in-place partitioning algorithm.

package quicksort;

/**
 *
 * @author a435104
 */
public class Main {

	static int callCount = 0;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        int[] array1 = {9,11,2,5,3,1,12};

        quicksort("main", array1);

        System.out.print("Sorted Array : ");
        printArray(array1);
    }

    /**
     * From - http://en.wikipedia.org/wiki/Quicksort
     *
     * Quicksort sorts by employing a divide and conquer strategy to divide a list into two sub-lists.
     * The steps are:
     *
   	 * 1. Pick an element, called a pivot, from the list.
     * 2. Reorder the list so that all elements which are less than the pivot come before the
     *    pivot and so that all elements greater than the pivot come after it (equal values can go either way).
     *    After this partitioning, the pivot is in its final position. This is called the partition operation.
     * 3. Recursively sort the sub-list of lesser elements and the sub-list of greater elements.
     *
     *
     */
    public static int[] quicksort(String debugString, int array[]) {

    	callCount++;

    	System.out.println("\nQuickSort -> callCount :" + callCount + " arrayName :" + debugString);
    	System.out.print("Array Elements    -> ");
    	printArray(array);

    	//base case
        if (array == null || array.length  " + pivot);

        // Create two arrays, one to hold the elements lesser than pivot
        // another to hold elements greater than pivot.
        int[] lesserArray = new int[array.length];
        int[] greaterArray = new int[array.length];

        int gndx = 0;
        int lndx = 0;

        // Next two for loops performs the partition operation.
        // Rearranges elements around pivot such that,
        // elements greater than or equal to pivot goes to greaterArray and
        // elements less than pivot goes to lesserArray.

        for (int ndx = 0; ndx = array[pivotNdx]) {
                greaterArray[gndx] = array[ndx];
                gndx++;
            }
            else {
                lesserArray[lndx] = array[ndx];
                lndx++;
            }
        }

        for (int ndx = pivotNdx + 1; ndx = array[pivotNdx]) {
                greaterArray[gndx] = array[ndx];
                gndx++;
            }
            else {
                lesserArray[lndx] = array[ndx];
                lndx++;
            }
        }
        // end of partitioning.

        // trim lesserArray
        int[] tempArray = new int[lndx];
        System.arraycopy(lesserArray, 0, tempArray, 0, lndx);
        lesserArray = tempArray;

        // trim greaterArray
        tempArray = new int[gndx];
        System.arraycopy(greaterArray, 0, tempArray, 0, gndx);
        greaterArray = tempArray;

        System.out.print("After partitioning, lesserArray -> ");
        printArray(lesserArray);

        System.out.print("After partitioning, greaterArray -> ");
        printArray(greaterArray);

        // recursively call quicksort on lesserArray and greaterArray.
        return concatenate(quicksort("lesserArray", lesserArray), pivot, quicksort("greaterArray", greaterArray), array);

    }

    private static int[] concatenate(int[] lesserArray, int pivot, int[] greaterArray, int[] array) {

        System.arraycopy(lesserArray, 0, array, 0, lesserArray.length);

        array[lesserArray.length] = pivot;

        System.arraycopy(greaterArray, 0, array, lesserArray.length + 1, greaterArray.length);

        return array;
    }

    private static void printArray(int array[]) {
        for (int i=0;i<array.length;i++) {
            System.out.print(array[i] + ", ");
        }

        System.out.println("");
    }
}

Comments (1)

Shell Script Tip : Case conversion

How to convert user input to a single case upper/lower for easy comparison?

Option 1: Use tr command

bash-3.00$ echo “unni” | tr ‘[a-z]‘ ‘[A-Z]‘
UNNI

Option 2: If you are using korn shell, use typeset command
#!/usr/bin/ksh

typeset -u VAR1
VAR1=”True”
echo $VAR1

Leave a Comment

Unix : SUID, SGID and Sticky Bit

bash-3.00$ chmod 4754 some_executable
bash-3.00$ ls -l
total 2
-rwsr-xr–   1 a435104  ccusers       50 Oct 17 05:28 some_executable

The extra “4″ ahead of the permission set “754″ specifies to always execute this file as the owner of the file.

The resulting permission has an “s” in place of “x”. This is called setting the SUID/SGID/Sticky Bit.

Good example of the use of SUID bit is /usr/bin/passwd

Only root user has permission to modify the /etc/passwd file. If that’s the case, how can a normal user change his password.

bash-3.00$ ls -l /etc/passwd
-rw-r–r–   1 root     sys         6001 Aug 27 10:00 /etc/passwd

/usr/bin/passwd has it’s SUID bit set. That means, irrespective of the user who is invoking the passwd program, the program always executes as the owner of the file (here root), granting it permission to modify /etc/passwd file.

bash-3.00$ ls -l /usr/bin/passwd
-r-sr-sr-x   1 root     sys        27228 Aug 16  2007 /usr/bin/passwd

And what is SGID used for ? It is used when  you want a program to execute always as a member of it’s owners group.

bash-3.00$ chmod 2754 some_executable

bash-3.00$ ls -l
total 2
-rwxr-sr–   1 a435104  ccusers       50 Oct 17 05:28 test.sh

Leave a Comment

Shell Script : Difference between $* and $@

$*   – All command line parameters

$@  – All command line parameters

“$*” – takes the entire list as one argument

“$@” – takes the entire list and seperates into seperate arguments

bash-3.00$ less test.sh
#!/usr/bin/sh

for str in “$*”
do
echo $str
done

bash-3.00$ ./test.sh a b c
a b c

bash-3.00$ less test.sh
#!/usr/bin/sh

for str in $*
do
echo $str
done

bash-3.00$ ./test.sh a b c
a
b
c

Comments (1)