Вы находитесь на странице: 1из 394

Return maximum occurring character in the input string

March 20, 2009

Write an efficient C function to return maximum occurring character in the input string e.g., if input string is test string then function should return t.

Algorithm:

Input string = test 1: Construct character count array from the input string. count['e'] = 1 count['s'] = 1 count['t'] = 2 2: Return the index of maximum value in count array (returns t).
Implementation:
#include <stdio.h> #include <stdlib.h> #define NO_OF_CHARS 256 int *getCharCountArray(char *); char getIndexOfMax(int *, int); /* Returns the maximum occurring character in the input string */ char getMaxOccuringChar(char *str) { int *count = getCharCountArray(str); return getIndexOfMax(count, NO_OF_CHARS); } /* Returns an array of size 256 containg count of characters in the passed char array */ int *getCharCountArray(char *str) { int *count = (int *)calloc(NO_OF_CHARS, sizeof(int)); int i;

for (i = 0; *(str+i); count[*(str+i)]++; return count; }

i++)

char getIndexOfMax(int ar[], int ar_size) { int i; int max_index = 0; for(i = 1; i < ar_size; i++) if(ar[i] > ar[max_index]) max_index = i; /* free memory allocated to count */ free(ar); ar = NULL; return max_index; } int main() { char str[] = "sample string"; printf("%c", getMaxOccuringChar(str)); getchar(); return 0; }

Time Complexity: O(n) Notes: If more than one character have the same and maximum count then function returns only the first character in alphabetical order. For example if input string is test sample then function will return only e.

How will you print numbers from 1 to 100 without using loop?
March 22, 2009

Here is a solution that prints numbers using recursion. Other alternatives for loop statements are recursion and goto statement, but use of goto is not suggestible as a general programming practice as goto statement changes the normal program execution sequence and makes it difficult to undestand and maintain.
#include <stdio.h>

/* Prints numbers from 1 to n */ void printNos(unsigned int n) { if(n > 0) { printNos(n-1); printf("%d ", n); } return; } /* Driver program to test printNos */ int main() { printNos(100); getchar(); return 0; }

Time Complexity: O(n) Now try writing a program that does the same but without any if construct.

How can we sum the digits of a given number in single statement?


March 22, 2009

Below are the solutions to get sum of the digits. 1. Iterative: The function has three lines instead of one line but it calculates sum in line. It can be made one line function if we pass pointer to sum.
# include<stdio.h> int main() { int n = 687; printf(" %d ", getSum(n)); getchar(); return 0; } /* Function to get sum of digits */ int getSum(int n) { int sum; /*Single line that calculates sum*/ for(sum=0; n > 0; sum+=n%10,n/=10); return sum; }

2. Recursive Thanks to ayesha for providing the below recursive solution.


int sumDigits(int no) { return no == 0 ? 0 : no%10 + sumDigits(no/10) ; } int main(void) { printf("%d", sumDigits(1352)); getchar(); return 0; }

Write a C program to calculate pow(x,n)


March 22, 2009

Below solution divides the problem into subproblems of size y/2 and call the subproblems recursively.
#include<stdio.h> /* Function to calculate x raised to the power y */ int power(int x, unsigned int y) { if( y == 0) return 1; else if (y%2 == 0) return power(x, y/2)*power(x, y/2); else return x*power(x, y/2)*power(x, y/2); } /* Program to test function power */ int main() { int x = 2; unsigned int y = 3; printf("%d", power(x, y)); getchar(); return 0; }

Time Complexity: O(n) Space Complexity: O(1) Algorithmic Paradigm: Divide and conquer.

Above function can be optimized to O(logn) by calculating power(x, y/2) only once and storing it.
/* Function to calculate x raised to the power y in O(logn)*/ int power(int x, unsigned int y) { int temp; if( y == 0) return 1; temp = power(x, y/2); if (y%2 == 0) return temp*temp; else return x*temp*temp; }

Time Complexity of optimized solution: O(logn) Let us extend the pow function to work for negative y and float x.
/* Extended version of power function that can work for float x and negative y*/ #include<stdio.h> float power(float x, int y) { float temp; if( y == 0) return 1; temp = power(x, y/2); if (y%2 == 0) return temp*temp; else { if(y > 0) return x*temp*temp; else return (temp*temp)/x; } } /* Program to test function power */ int main() { float x = 2; int y = -3; printf("%f", power(x, y)); getchar(); return 0; }

Remove all duplicates from the input string.


March 22, 2009

Below are the different methods to remove duplicates in a string. METHOD 1 (Use Sorting)

Algorithm:

1) Sort the elements. 2) Now in a loop, remove duplicates by comparing the current character with previous character. 3) Remove extra characters at the end of the resultant string.
Example:

Input string: geeksforgeeks 1) Sort the characters eeeefggkkosss 2) Remove duplicates efgkosgkkosss 3) Remove extra characters efgkos
Note that, this method doesnt keep the original order of the input string. For example, if we are to remove duplicates for geeksforgeeks and keep the order of characters same, then output should be geksfor, but above function returns efgkos. We can modify this method by storing the original order. METHOD 2 keeps the order same. Implementation:
# include <stdio.h> # include <stdlib.h> /* Function to remove duplicates in a sorted array */ char *removeDupsSorted(char *str); /* Utitlity function to sort array A[] */ void quickSort(char A[], int si, int ei); /* Function removes duplicate characters from the string This function work in-place and fills null characters in the extra space left */ char *removeDups(char *str) { int len = strlen(str);

quickSort(str, 0, len-1); return removeDupsSorted(str); } /* Function to remove duplicates in a sorted array */ char *removeDupsSorted(char *str) { int res_ind = 1, ip_ind = 1; /* In place removal of duplicate characters*/ while(*(str + ip_ind)) { if(*(str + ip_ind) != *(str + ip_ind - 1)) { *(str + res_ind) = *(str + ip_ind); res_ind++; } ip_ind++; } /* After above step string is stringiittg. Removing extra iittg after string*/ *(str + res_ind) = '\0'; return str; } /* Driver program to test removeDups */ int main() { char str[] = "eeeefggkkosss"; printf("%s", removeDups(str)); getchar(); return 0; } /* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING PURPOSE */ void exchange(char *a, char *b) { char temp; temp = *a; *a = *b; *b = temp; } int partition(char A[], int si, int ei) { char x = A[ei]; int i = (si - 1); int j; for (j = si; j <= ei - 1; j++) { if(A[j] <= x) { i++; exchange(&A[i], &A[j]); }

} exchange (&A[i + 1], &A[ei]); return (i + 1); } /* Implementation of Quick Sort A[] --> Array to be sorted si --> Starting index ei --> Ending index */ void quickSort(char A[], int si, int ei) { int pi; /* Partitioning index */ if(si < ei) { pi = partition(A, si, ei); quickSort(A, si, pi - 1); quickSort(A, pi + 1, ei); } }

Time Complexity: O(nlogn) If we use some nlogn sorting algorithm instead of quicksort.

METHOD 2 (Use Hashing ) Algorithm:

1: Initialize: str = "test string" /* input string */ ip_ind = 0 /* index to keep track of location of next character in input string */ res_ind = 0 /* index to keep track of location of next character in the resultant string */ bin_hash[0..255] = {0,0, .} /* Binary hash to see if character is already processed or not */ 2: Do following for each character *(str + ip_ind) in input string:

(a) if bin_hash is not set for *(str + ip_ind) then // if program sees the character *(str + ip_ind) first time (i) Set bin_hash for *(str + ip_ind) (ii) Move *(str + ip_ind) to the resultant string. This is done inplace. (iii) res_ind++ (b) ip_ind++ /* String obtained after this step is "te sringng" */ 3: Remove extra characters at the end of the resultant string. /* String obtained after this step is "te sring" */
Implementation:
# # # # include <stdio.h> include <stdlib.h> define NO_OF_CHARS 256 define bool int

/* Function removes duplicate characters from the string This function work in-place and fills null characters in the extra space left */ char *removeDups(char *str) { bool bin_hash[NO_OF_CHARS] = {0}; int ip_ind = 0, res_ind = 0; char temp; /* In place removal of duplicate characters*/ while(*(str + ip_ind)) { temp = *(str + ip_ind); if(bin_hash[temp] == 0) { bin_hash[temp] = 1; *(str + res_ind) = *(str + ip_ind); res_ind++; } ip_ind++; }

/* After above step string is stringiittg. Removing extra iittg after string*/ *(str+res_ind) = '\0'; return str; } /* Driver program to test removeDups */ int main() { char str[] = "geeksforgeeks"; printf("%s", removeDups(str)); getchar(); return 0; }

Time Complexity: O(n) NOTES: * It is assumed that number of possible characters in input string are 256. NO_OF_CHARS should be changed accordingly. * calloc is used instead of malloc for memory allocations of counting array (count) to initialize allocated memory to \0. malloc() followed by memset() could also be used. * Above algorithm also works for an integer array inputs if range of the integers in array is given. Example problem is to find maximum occurring number in an input array given that the input array contain integers only between 1000 to 1100

Remove all duplicates from the input string.


March 22, 2009

Below are the different methods to remove duplicates in a string. METHOD 1 (Use Sorting) Algorithm:

1) Sort the elements. 2) Now in a loop, remove duplicates by comparing the current character with previous character. 3) Remove extra characters at the end of the resultant string.

Example:

Input string: geeksforgeeks 1) Sort the characters eeeefggkkosss 2) Remove duplicates efgkosgkkosss 3) Remove extra characters efgkos
Note that, this method doesnt keep the original order of the input string. For example, if we are to remove duplicates for geeksforgeeks and keep the order of characters same, then output should be geksfor, but above function returns efgkos. We can modify this method by storing the original order. METHOD 2 keeps the order same. Implementation:
# include <stdio.h> # include <stdlib.h> /* Function to remove duplicates in a sorted array */ char *removeDupsSorted(char *str); /* Utitlity function to sort array A[] */ void quickSort(char A[], int si, int ei); /* Function removes duplicate characters from the string This function work in-place and fills null characters in the extra space left */ char *removeDups(char *str) { int len = strlen(str); quickSort(str, 0, len-1); return removeDupsSorted(str); } /* Function to remove duplicates in a sorted array */ char *removeDupsSorted(char *str) { int res_ind = 1, ip_ind = 1; /* In place removal of duplicate characters*/ while(*(str + ip_ind)) { if(*(str + ip_ind) != *(str + ip_ind - 1)) { *(str + res_ind) = *(str + ip_ind);

res_ind++; } ip_ind++; } /* After above step string is stringiittg. Removing extra iittg after string*/ *(str + res_ind) = '\0'; return str; } /* Driver program to test removeDups */ int main() { char str[] = "eeeefggkkosss"; printf("%s", removeDups(str)); getchar(); return 0; } /* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING PURPOSE */ void exchange(char *a, char *b) { char temp; temp = *a; *a = *b; *b = temp; } int partition(char A[], int si, int ei) { char x = A[ei]; int i = (si - 1); int j; for (j = si; j <= ei - 1; j++) { if(A[j] <= x) { i++; exchange(&A[i], &A[j]); } } exchange (&A[i + 1], &A[ei]); return (i + 1); } /* Implementation of Quick Sort A[] --> Array to be sorted si --> Starting index ei --> Ending index */ void quickSort(char A[], int si, int ei) { int pi; /* Partitioning index */ if(si < ei) { pi = partition(A, si, ei);

quickSort(A, si, pi - 1); quickSort(A, pi + 1, ei); } }

Time Complexity: O(nlogn) If we use some nlogn sorting algorithm instead of quicksort.

METHOD 2 (Use Hashing ) Algorithm:

1: Initialize: str = "test string" /* input string */ ip_ind = 0 /* index to keep track of location of next character in input string */ res_ind = 0 /* index to keep track of location of next character in the resultant string */ bin_hash[0..255] = {0,0, .} /* Binary hash to see if character is already processed or not */ 2: Do following for each character *(str + ip_ind) in input string: (a) if bin_hash is not set for *(str + ip_ind) then // if program sees the character *(str + ip_ind) first time (i) Set bin_hash for *(str + ip_ind) (ii) Move *(str + ip_ind) to the resultant string. This is done inplace.

(iii) res_ind++ (b) ip_ind++ /* String obtained after this step is "te sringng" */ 3: Remove extra characters at the end of the resultant string. /* String obtained after this step is "te sring" */
Implementation:
# # # # include <stdio.h> include <stdlib.h> define NO_OF_CHARS 256 define bool int

/* Function removes duplicate characters from the string This function work in-place and fills null characters in the extra space left */ char *removeDups(char *str) { bool bin_hash[NO_OF_CHARS] = {0}; int ip_ind = 0, res_ind = 0; char temp; /* In place removal of duplicate characters*/ while(*(str + ip_ind)) { temp = *(str + ip_ind); if(bin_hash[temp] == 0) { bin_hash[temp] = 1; *(str + res_ind) = *(str + ip_ind); res_ind++; } ip_ind++; } /* After above step string is stringiittg. Removing extra iittg after string*/ *(str+res_ind) = '\0'; return str; } /* Driver program to test removeDups */ int main() { char str[] = "geeksforgeeks"; printf("%s", removeDups(str)); getchar(); return 0; }

Time Complexity: O(n) NOTES: * It is assumed that number of possible characters in input string are 256. NO_OF_CHARS should be changed accordingly. * calloc is used instead of malloc for memory allocations of counting array (count) to initialize allocated memory to \0. malloc() followed by memset() could also be used. * Above algorithm also works for an integer array inputs if range of the integers in array is given. Example problem is to find maximum occurring number in an input array given that the input array contain integers only between 1000 to 1100

Write a function to get Nth node in a Linked List


March 26, 2009

Write a GetNth() function that takes a linked list and an integer index and returns the data value stored in the node at that index position.

Algorithm:

1. Initialize count = 0 2. Loop through the link list a. if count is equal to the passed index then return current node b. Increment count c. change current to point to next of the current.
Implementation:
#include <stdio.h> #include <stdlib.h> #include <assert.h> /* Link list node */ struct node { int data; struct node* next; };

/* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node)); /* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to point to the new node */ (*head_ref) = new_node; } /* Takes head pointer of the linked list and index as arguments and return data at index*/ int GetNth(struct node* head, int index) { struct node* current = head; int count = 0; /* the index of the node we're currently looking at */ while (current != NULL) { if (count == index) return(current->data); count++; current = current->next; } /* if we get to this line, the caller was asking for a non-existent element so we assert fail */ assert(0); } /* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL; /* Use push() to construct below list 1->12->1->4->1 */ push(&head, 1); push(&head, 4); push(&head, 1); push(&head, 12); push(&head, 1); /* Check the count function */ printf("Element at index 3 is %d", GetNth(head, 3)); getchar(); }

Time Complexity: O(n)

Given only a pointer to a node to be deleted in a singly linked list, how do you delete it?
April 16, 2009

A simple solution is to traverse the linked list until you find the node you want to delete. But this solution requires pointer to the head node which contradicts the problem statement. Fast solution is to copy the data from the next node to the node to be deleted and delete the next node. Something like following.

struct node *temp = node_ptr->next; node_ptr->data = temp->data; node_ptr->next = temp->next; free(temp);


Program:
#include<stdio.h> #include<assert.h> #include<stdlib.h> /* Link list node */ struct node { int data; struct node* next; }; /* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node)); /* put in the data */ new_node->data = new_data; /* link the old list off the new node */ new_node->next = (*head_ref); /* move the head to point to the new node */ (*head_ref) = new_node; }

void printList(struct node *head) { struct node *temp = head; while(temp != NULL) { printf("%d ", temp->data); temp = temp->next; } } void deleteNode(struct node *node_ptr) { struct node *temp = node_ptr->next; node_ptr->data = temp->data; node_ptr->next = temp->next; free(temp); } /* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL; /* Use push() to construct below list 1->12->1->4->1 */ push(&head, 1); push(&head, 4); push(&head, 1); push(&head, 12); push(&head, 1); printf("\n Before deleting \n"); printList(head); /* I m deleting the head itself. You can check for more cases */ deleteNode(head); printf("\n After deleting \n"); printList(head); getchar(); return 0; }

This solution doesnt work if the node to be deleted is the last node of the list. To make this solution work we can mark the end node as a dummy node. But the programs/functions that are using this function should also be modified.

Remove characters from the first string which are present in the second string
May 23, 2009

Write an efficient C function that takes two strings as arguments and removes the characters from first string which are present in second string (mask string). Algorithm: Let first input string betest string and the string which has characters to be removed from first string be mask 1: Initialize: res_ind = 0 /* index to keep track of processing of each character in i/p string */ ip_ind = 0 /* index to keep track of processing of each character in the resultant string */ 2: Construct count array from mask_str. Count array would be: (We can use Boolean array here instead of int count array because we dont need count, we need to know only if character is present in mask string) count['a'] = 1 count['k'] = 1 count['m'] = 1 count['s'] = 1 3: Process each character of the input string and if count of that character is 0 then only add the character to the resultant string. str = tet tringng // s has been removed because s was present in mask_str but we we have got two extra characters ng ip_ind = 11 res_ind = 9 4: Put a \0 at the end of the string? Implementation:
#include <stdio.h> #include <stdlib.h> #define NO_OF_CHARS 256 /* Returns an array of size 256 containg count of characters in the passed char array */ int *getCharCountArray(char *str) { int *count = (int *)calloc(sizeof(int), NO_OF_CHARS); int i; for (i = 0; *(str+i); i++) count[*(str+i)]++;

return count; } /* removeDirtyChars takes two string as arguments: First string (str) is the one from where function removes dirty characters. Second string is the string which contain all dirty characters which need to be removed from first string */ char *removeDirtyChars(char *str, char *mask_str) { int *count = getCharCountArray(mask_str); int ip_ind = 0, res_ind = 0; char temp; while(*(str + ip_ind)) { temp = *(str + ip_ind); if(count[temp] == 0) { *(str + res_ind) = *(str + ip_ind); res_ind++; } ip_ind++; } /* After above step string is ngring. Removing extra "iittg" after string*/ *(str+res_ind) = '\0'; return str; } /* Driver program to test getCharCountArray*/ int main() { char mask_str[] = "mask"; char str[] = "geeksforgeeks"; printf("%s", removeDirtyChars(str, mask_str)); getchar(); return 0; }

Time Complexity: O(m+n) Where m is the length of mask string and n is the length of the input string.

A Program to check if strings are rotations of each other or not


May 26, 2009

Given a string s1 and a string s2, write a snippet to say whether s2 is a rotation of s1 using only one call to strstr routine? (eg given s1 = ABCD and s2 = CDAB, return true, given s1 = ABCD, and s2 = ACBD , return false)

Algorithm: areRotations(str1, str2)

1. Create a temp string and store concatenation of str1 to str1 in temp. temp = str1.str1 2. If str2 is a substring of temp then str1 and str2 are rotations of each other. Example: str1 = "ABACD" str2 = "CDABA" temp = str1.str1 = "ABACDABACD" Since str2 is a substring of temp, str1 and str2 are rotations of each other.
Implementation:
# include <stdio.h> # include <string.h> # include <stdlib.h> /* Function checks if passed strings (str1 and str2) are rotations of each other */ int areRotations(char *str1, char *str2) { int size1 = strlen(str1); int size2 = strlen(str2); char *temp; void *ptr; /* Check if sizes of two strings are same */ if(size1 != size2) return 0; /* Create a temp string with value str1.str1 */ temp = (char *)malloc(sizeof(char)*size1*2 + 1); temp[0] = '\0'; strcat(temp, str1); strcat(temp, str1); /* Now check if str2 is a substring of temp */ ptr = strstr(temp, str2); /* strstr returns NULL if the second string is NOT a substring of first string */ if(ptr != NULL) return 1;

else return 0; } /* Driver program to test areRotations */ int main() { char *str1 = "ABCD"; char *str2 = "ABCDA"; if(areRotations(str1, str2)) printf("Strings are rotations of each other"); else printf("Strings are not rotations of each other"); getchar(); return 0; }

Library Functions Used: strstr: strstr finds a sub-string within a string. Prototype: char * strstr(const char *s1, const char *s2); See http://www.lix.polytechnique.fr/Labo/Leo.Liberti/public/computing/ prog/c/C/MAN/strstr.htm for more details strcat: strncat concatenate two strings Prototype: char *strcat(char *dest, const char *src); See http://www.lix.polytechnique.fr/Labo/Leo.Liberti/public/computing/ prog/c/C/MAN/strcat.htm for more details Time Complexity: Time complexity of this problem depends on the implementation of strstr function. If implementation of strstr is done using KMP matcher then complexity of the above program is (-)(n1 + n2) where n1 and n2 are lengths of strings. KMP matcher takes (-)(n) time to find a substrng in a string of length n where length of substring is assumed to be smaller than the string.

Output of the program | Dereference, Reference, Dereference, Reference.


May 27, 2009

Predict the output of below program

int main() { char *ptr = "geeksforgeeks"; printf("%c\n", *&*&*ptr); getchar(); return 0; }

Output: g Explanation: The operator * is used for dereferencing and the operator & is used to get the address. These operators cancel effect of each other when used one after another. We can apply them alternatively any no. of times. For example *ptr gives us g, &*ptr gives address of g, *&*ptr again g, &*&*ptr address of g, and finally *&*&*ptr gives g Now try below
int main() { char *ptr = "geeksforgeeks"; printf("%s\n", *&*&ptr); getchar(); return 0; }

Output of the Program | Use Macros Carefully!


May 27, 2009

Predict the output of the below program


#define square(x) x*x int main() { int x; x = 36/square(6); printf("%d",x); getchar(); return 0; }

Output: 36 Explanation: Preprocessor replaces square(6) by 6*6 and the expression becomes

x = 36/6*6 and value of x is calculated as 36. If we want correct behavior from macro square(x), we should declare it as #define square(x) ((x)*(x)) /* Note that the expression (x*x) will also fail for square(6-2) */

Output of the Program | Pointer to a Constant or Constant Pointer?


May 27, 2009

Predict the output of the below program.


int main() { int x = 5; int * const ptr = &x; ++(*ptr); printf("%d", x); getchar(); return 0; }

Output: 6 Explananation: See following declarations to know the difference between constant pointer and a pointer to a constant. int * const ptr > ptr is constant pointer. You can change the value at the location pointed by pointer p, but you can not change p to point to other location. int const * ptr > ptr is a pointer to a constant. You can change ptr to point other variable. But you cannot change the value pointed by ptr. Therefore above program works well because we have a constant pointer and we are not changing ptr to point to any other location. We are only icrementing value pointed by ptr. Try below program, you will get compiler error.
int main() { int x = 5; int const * ptr = &x; ++(*ptr); printf("%d", x);

getchar(); return 0; }

Write a C program to print Geeks for Geeks without using a semicolon


May 28, 2009

Use printf statement inside the if condition


#include<stdio.h> int main() { if( printf( "Geeks for Geeks" ) ) { } }

One trivial extension of the above problem: Write a C program to print ; without using a semicolon
#include<stdio.h> int main() { if(printf("%c",59)) { } }

Write a one line C function to round floating point numbers


May 28, 2009

Algorithm: roundNo(num) 1. If num is positive then add 0.5. 2. Else subtract 0.5. 3. Type cast the result to int and return.

Example: num = 1.67, (int) num + 0.5 = (int)2.17 = 2 num = -1.67, (int) num 0.5 = -(int)2.17 = -2 Implementation:
/* Program for rounding floating point numbers */ # include<stdio.h> int roundNo(float num) { return num < 0 ? num - 0.5 : num + 0.5;

} int main() { printf("%d", roundNo(-1.777)); getchar(); return 0; }

Output: -2 Time complexity: O(1) Space complexity: O(1) Now try rounding for a given precision. i.e., if given precision is 2 then function should return 1.63 for 1.63322 and -1.63 for 1.6332.

Next Power of 2
May 28, 2009

Write a function that, for a given no n, finds a number p which is greater than or equal to n and is a power of 2.

IP 5 OP 8 IP 17 OP 32 IP 32 OP 32
There are plenty of solutions for this. Let us take the example of 17 to explain some of them.

Method 1(Using Log of the number)

1. Calculate Position of set bit in p(next power of 2): pos = ceil(lgn) (ceiling of log n with base 2) 2. Now calculate p:

p
Example

= pow(2, pos)

Let us try for 17 pos = 5 p = 32


Method 2 (By getting the position of only set bit in result )

/* If n is a power of 2 then return n */ 1 If (n & !(n&(n-1))) then return n 2 Else keep right shifting n until it becomes zero and count no of shifts a. Initialize: count = 0 b. While n ! = 0 n = n>>1 count = count + 1 /* Now count has the position of set bit in result */ 3 Return (1 << count)
Example:

Let us try for 17 count = 5 p = 32


unsigned int nextPowerOf2(unsigned int n) { unsigned count = 0; /* First n in the below condition is for the case where n is 0*/ if (n & !(n&(n-1))) return n; while( n != 0) { n >>= 1; count += 1; } return 1<<count;

} /* Driver program to test above function */ int main() { unsigned int n = 0; printf("%d", nextPowerOf2(n)); getchar(); return 0; }

Method 3(Shift result one by one) Thanks to coderyogi for suggesting this method . This method is a variation of method 2 where instead of getting count, we shift the result one by one in a loop.
unsigned int nextPowerOf2(unsigned int n) { unsigned int p = 1; if (n & !(n & (n - 1))) return n; while (p < n) { p <<= 1; } return p; } /* Driver program to test above function */ int main() { unsigned int n = 5; printf("%d", nextPowerOf2(n)); getchar(); return 0; }

Time Complexity: O(lgn)

Method 4(Customized and Fast)

1. Subtract n by 1 n = n -1 2. Set all bits after the leftmost set bit.

/* Below solution 32 bits */ n = n n = n n = n n = n n = n 3. Return n + 1


Example:

works only if integer is | | | | | (n (n (n (n (n >> >> >> >> >> 1); 2); 4); 8); 16);

Steps 1 & 3 of above algorithm are to handle cases of power of 2 numbers e.g., 1, 2, 4, 8, 16, Let us step 1 n = step 2 n = n = n = n = n = n = n = n = n = n = n = n = n = n = n = try for 17(10001) n - 1 = 16 (10000) n | n 10000 11000 n | n 11000 11110 n | n 11110 11111 n | n 11111 11111 n | n 11110 11111 >> 1 | 01000 >> 2 | 00110 >> 4 | 00001 >> 8 | 00000 >> 16 | 00000

step 3: Return n+1 We get n + 1 as 100000 (32)


Program:

# include <stdio.h> /* Finds next power of two for n. If n itself is a power of two then returns n*/ unsigned int nextPowerOf2(unsigned int n) { n--; n |= n >> 1; n |= n >> 2; n |= n >> 4; n |= n >> 8; n |= n >> 16; n++; return n; } /* Driver program to test above function */ int main() { unsigned int n = 5; printf("%d", nextPowerOf2(n)); getchar(); return 0; }

Time Complexity: O(lgn) References: http://en.wikipedia.org/wiki/Power_of_2

Given an array A[] and a number x, check for pair in A[] with sum as x
May 30, 2009

Write a C program that, given an array A[] of n numbers and another number x, determines whether or not there exist two elements in S whose sum is exactly x. METHOD 1 (Use Sorting) Algorithm:

hasArrayTwoCandidates (A[], ar_size, sum) 1) Sort the array in non-decreasing order. 2) Initialize two index variables to find the candidate

elements in the sorted array. (a) Initialize first to the leftmost index: l = 0 (b) Initialize second the rightmost index: r = ar_size-1 3) Loop while l < r. (a) If (A[l] + A[r] == sum) then return 1 (b) Else if( A[l] + A[r] < sum ) then l++ (c) Else r-4) No candidates in whole array - return 0
Time Complexity: Depends on what sorting algorithm we use. If we use Merge Sort or Heap Sort then (-)(nlogn) in worst case. If we use Quick Sort then O(n^2) in worst case. Auxiliary Space : Again, depends on sorting algorithm. For example auxiliary space is O(n) for merge sort and O(1) for Heap Sort. Example: Let Array be {1, 4, 45, 6, 10, -8} and sum to find be 16 Sort the array A = {-8, 1, 4, 6, 10, 45} Initialize l = 0, r = 5 A[l] + A[r] ( -8 + 45) > 16 => decrement r. Now r = 10 A[l] + A[r] ( -8 + 10) < 2 => increment l. Now l = 1 A[l] + A[r] ( 1 + 10) < 16 => increment l. Now l = 2 A[l] + A[r] ( 4 + 10) < 14 => increment l. Now l = 3 A[l] + A[r] ( 6 + 10) == 16 => Found candidates (return 1) Note: If there are more than one pair having the given sum then this algorithm reports only one. Can be easily extended for this though. Implementation:
# include <stdio.h> # define bool int void quickSort(int *, int, int);

bool hasArrayTwoCandidates(int A[], int arr_size, int sum) { int l, r; /* Sort the elements */ quickSort(A, 0, arr_size-1); /* Now look for the array*/ l = 0; r = arr_size-1; while(l < r) { if(A[l] + A[r] return 1; else if(A[l] + l++; else // A[i] + r--; } return 0; } /* Driver program to test above function */ int main() { int A[] = {1, 4, 45, 6, 10, -8}; int n = 16; int arr_size = 6; if( hasArrayTwoCandidates(A, arr_size, n)) printf("Array has two elements with sum 16"); else printf("Array doesn't have two elements with sum 16 "); getchar(); return 0; } /* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING PURPOSE */ void exchange(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int partition(int A[], int si, int ei) { int x = A[ei]; int i = (si - 1); int j; for (j = si; j <= ei - 1; j++) { if(A[j] <= x) two candidates in the sorted

== sum) A[r] < sum) A[j] > sum

{ i++; exchange(&A[i], &A[j]); } } exchange (&A[i + 1], &A[ei]); return (i + 1); } /* Implementation of Quick Sort A[] --> Array to be sorted si --> Starting index ei --> Ending index */ void quickSort(int A[], int si, int ei) { int pi; /* Partitioning index */ if(si < ei) { pi = partition(A, si, ei); quickSort(A, si, pi - 1); quickSort(A, pi + 1, ei); } }

METHOD 2 (Use Hash Map) Thanks to Bindu for suggesting this method and thanks to Shekhu for providing code. This method works in O(n) time if range of numbers is known. Let sum be the given sum and A[] be the array in which we need to find pair.

1) Initialize Binary Hash Map M[] = {0, 0, } 2) Do following for each element A[i] in A[] (a) If M[x - A[i]] is set then print the pair (A[i], x A[i]) (b) Set M[A[i]]
Implementation:
#include <stdio.h> #define MAX 100000 void printPairs(int arr[], int arr_size, int sum) { int i, temp; bool binMap[MAX] = {0}; /*initialize hash map as 0*/ for(i = 0; i < arr_size; i++)

{ temp = sum - arr[i]; if(temp >= 0 && binMap[temp] == 1) { printf("Pair with given sum %d is (%d, %d) \n", sum, arr[i], temp); } binMap[arr[i]] = 1; } } /* Driver program to test above function */ int main() { int A[] = {1, 4, 45, 6, 10, 8}; int n = 16; int arr_size = 6; printPairs(A, arr_size, n); getchar(); return 0; }

Time Complexity: O(n) Auxiliary Space: O(R) where R is range of integers. If range of numbers include negative numbers then also it works. All we have to do for negative numbers is to make everything positive by adding the absolute value of smallest negative integer to all numbers.

Majority Element
May 30, 2009

Majority Element: A majority element in an array A[] of size n is an element that appears more than n/2 times (and hence there is at most one such element). Write a function which takes an array and emits the majority element (if it exists), otherwise prints NONE as follows:

I/P : 3 3 4 2 4 4 2 4 4 O/P : 4 I/P : 3 3 4 2 4 4 2 4 O/P : NONE


METHOD 1 (Basic) The basic solution is to have two loops and keep track of maximum

count for all different elements. If maximum count becomes greater than n/2 then break the loops and return the element having maximum count. If maximum count doesnt become more than n/2 then majority element doesnt exist. Time Complexity: O(n*n). Auxiliary Space : O(1).

METHOD 2 (Using Binary Search Tree) Thanks to Sachin Midha for suggesting this solution. Node of the Binary Search Tree (used in this approach) will be as follows.
struct tree { int element; int count; }BST;

Insert elements in BST one by one and if an element is already present then increment the count of the node. At any stage, if count of a node becomes more than n/2 then return. The method works well for the cases where n/2+1 occurrences of the majority element is present in the starting of the array, for example {1, 1, 1, 1, 1, 2, 3, 4}. Time Complexity: If a binary search tree is used then time complexity will be O(n^2). If a self-balancing-binary-search tree is used then O(nlogn) Auxiliary Space: O(n)

METHOD 3 (Using Moores Voting Algorithm) This is a two step process. 1. Get an element occurring most of the time in the array. This phase will make sure that if there is a majority element then it will return that

only. 2. Check if the element obtained from above step is majority element. 1. Finding a Candidate: The algorithm for first phase that works in O(n) is known as Moores Voting Algorithm. Basic idea of the algorithm is if we cancel out each occurrence of an element e with all the other elements that are different from e then e will exist till end if it is a majority element.

findCandidate(a[], size) 1. Initialize index and count of majority element maj_index = 0, count = 1 2. Loop for i = 1 to size 1 (a)If a[maj_index] == a[i] count++ (b)Else count--; (c)If count == 0 maj_index = i; count = 1 3. Return a[maj_index]
Above algorithm loops through each element and maintains a count of a[maj_index], If next element is same then increments the count, if next element is not same then decrements the count, and if the count reaches 0 then changes the maj_index to the current element and sets count to 1. First Phase algorithm gives us a candidate element. In second phase we need to check if the candidate is really a majority element. Second phase is simple and can be easily done in O(n). We just need to check if count of the candidate element is greater than n/2. Example: A[] = 2, 2, 3, 5, 2, 2, 6 Initialize: maj_index = 0, count = 1 > candidate 2? 2, 2, 3, 5, 2, 2, 6

Same as a[maj_index] => count = 2 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 1 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 0 Since count = 0, change candidate for majority element to 5 => maj_index = 3, count = 1 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 0 Since count = 0, change candidate for majority element to 2 => maj_index = 4 2, 2, 3, 5, 2, 2, 6 Same as a[maj_index] => count = 2 2, 2, 3, 5, 2, 2, 6 Different from a[maj_index] => count = 1 Finally candidate for majority element is 2. First step uses Moores Voting Algorithm to get a candidate for majority element. 2. Check if the element obtained in step 1 is majority

printMajority (a[], size) 1. Find the candidate for majority 2. If candidate is majority. i.e., appears more than n/2 times. Print the candidate 3. Else Print "NONE"
Implementation of method 3:
/* Program for finding out majority element in an array */ # include<stdio.h> # define bool int

int findCandidate(int *, int); bool isMajority(int *, int, int); /* Function to print Majority Element */ void printMajority(int a[], int size) { /* Find the candidate for Majority*/ int cand = findCandidate(a, size); /* Print the candidate if it is Majority*/ if(isMajority(a, size, cand)) printf(" %d ", cand); else printf("NO Majority Element"); } /* Function to find the candidate for Majority */ int findCandidate(int a[], int size) { int maj_index = 0, count = 1; int i; for(i = 1; i < size; i++) { if(a[maj_index] == a[i]) count++; else count--; if(count == 0) { maj_index = i; count = 1; } } return a[maj_index]; } /* Function to check if the candidate occurs more than n/2 times */ bool isMajority(int a[], int size, int cand) { int i, count = 0; for (i = 0; i < size; i++) if(a[i] == cand) count++; if (count > size/2) return 1; else return 0; } /* Driver function to test above functions */ int main() { int a[] = {1, 3, 3, 1, 2}; printMajority(a, 5); getchar(); return 0; }

Time Complexity: O(n) Auxiliary Space : O(1) Now give a try to below question Given an array of 2n elements of which n elements are same and the remaining n elements are all different. Write a C program to find out the value which is present n times in the array. There is no restriction on the elements in the array. They are random (In particular they not sequential).

Write an Efficient Method to Check if a Number is Multiple of 3


May 30, 2009

The very first solution that comes to our mind is the one that we learned in school. If sum of digits in a number is multiple of 3 then number is multiple of 3 e.g., for 612 sum of digits is 9 so its a multiple of 3. But this solution is not efficient. You have to get all decimal digits one by one, add them and then check if sum is multiple of 3. There is a pattern in binary representation of the number that can be used to find if number is a multiple of 3. If difference between count of odd set bits (Bits set at odd positions) and even set bits is multiple of 3 then is the number. Example: 23 (00..10111) 1) Get count of all set bits at odd positions (For 23 its 3). 2) Get count of all set bits at even positions (For 23 its 1). 3) If difference of above two counts is a multiple of 3 then number is also a multiple of 3. (For 23 its 2 so 23 is not a multiple of 3) Take some more examples like 21, 15, etc

Algorithm: isMutlipleOf3(n) 1) Make n positive if n is negative. 2) If number is 0 then return 1 3) If number is 1 then return 0 4) Initialize: odd_count = 0, even_count = 0 5) Loop while n != 0

a) If rightmost bit is set then increment odd count. b) Right-shift n by 1 bit c) If rightmost bit is set then increment even count. d) Right-shift n by 1 bit 6) return isMutlipleOf3(odd_count - even_count)
Proof: Above can be proved by taking the example of 11 in decimal numbers. (In this context 11 in decimal numbers is same as 3 in binary numbers) If difference between sum of odd digits and even digits is multiple of 11 then decimal number is multiple of 11. Lets see how. Lets take the example of 2 digit numbers in decimal AB = 11A -A + B = 11A + (B A) So if (B A) is a multiple of 11 then is AB. Let us take 3 digit numbers. ABC = 99A + A + 11B B + C = (99A + 11B) + (A + C B) So if (A + C B) is a multiple of 11 then is (A+C-B) Let us take 4 digit numbers now. ABCD = 1001A + D + 11C C + 999B + B A = (1001A 999B + 11C) + (D + B A -C ) So, if (B + D A C) is a multiple of 11 then is ABCD. This can be continued for all decimal numbers. Above concept can be proved for 3 in binary numbers in the same way. Time Complexity: O(logn) Program:
#include<stdio.h> /* Fnction to check if n is a multiple of 3*/ int isMultipleOf3(int n) {

int odd_count = 0; int even_count = 0; /* Make no positive if +n is multiple of 3 then is -n. We are doing this to avoid stack overflow in recursion*/ if(n < 0) n = -n; if(n == 0) return 1; if(n == 1) return 0; while(n) { /* If odd bit is set then increment odd counter */ if(n & 1) odd_count++; n = n>>1; /* If even bit is set then increment even counter */ if(n & 1) even_count++; n = n>>1; } return isMultipleOf3(abs(odd_count - even_count)); } /* Program to test function isMultipleOf3 */ int main() { int num = 23; if (isMultipleOf3(num)) printf("num is multiple of 3"); else printf("num is not a multiple of 3"); getchar(); return 0; }

Write a C program to find the parity of an unsigned integer


May 30, 2009

Parity: Parity of a number refers to whether it contains an odd or even number of 1-bits. The number has odd parity, if it contains odd number of 1-bits and is even parity if it contains even number of 1bits. Main idea of the below solution is Loop while n is not 0 and in loop unset one of the set bits and invert parity.

Algorithm: getParity(n) 1. Initialize parity = 0 2. Loop while n != 0 a. Invert parity

parity = !parity b. Unset rightmost set bit n = n & (n-1) 3. return parity Example: Initialize: n = 13 (1101) parity = 0

n = 13 & 12 = 12 (1100) parity = 1 n = 12 & 11 = 8 (1000) parity = 0 n = 8 & 7 = 0 (0000) parity = 1


Program:
# include <stdio.h> # define bool int /* Function to get parity of number n. It returns 1 if n has odd parity, and returns 0 if n has even parity */ bool getParity(unsigned int n) { bool parity = 0; while (n) { parity = !parity; n = n & (n - 1); } return parity; } /* Driver program to test getParity() */ int main() { unsigned int n = 7; printf("Parity of no %d = %s", n, (getParity(n)? "odd": "even")); getchar(); return 0; }

Above solution can be optimized by using lookup table. Please refer to Bit Twiddle Hacks[1st reference] for details. Time Complexity: The time taken by above algorithm is proportional to the number of bits set. Worst case complexity is O(Logn).

Uses: Parity is used in error detection and cryptography. References: http://graphics.stanford.edu/~seander/bithacks.html#ParityNaive last checked on 30 May 2009.

Write a C program to reverse digits of a number


May 30, 2009

ITERATIVE WAY Algorithm:

Input: num (1) Initialize rev_num = 0 (2) Loop while num > 0 (a) Multiply rev_num by 10 and add remainder of num divide by 10 to rev_num rev_num = rev_num*10 + num%10; (b) Divide num by 10 (3) Return rev_num
Example: num = 4562 rev_num = 0 rev_num = rev_num *10 + num%10 = 2 num = num/10 = 456 rev_num = rev_num *10 + num%10 = 20 + 6 = 26 num = num/10 = 45 rev_num = rev_num *10 + num%10 = 260 + 5 = 265 num = num/10 = 4 rev_num = rev_num *10 + num%10 = 265 + 4 = 2654 num = num/10 = 0 Program:
#include <stdio.h>

/* Iterative function to reverse digits of num*/ int reversDigits(int num) { int rev_num = 0; while(num > 0) { rev_num = rev_num*10 + num%10; num = num/10; } return rev_num; } /*Driver program to test reversDigits*/ int main() { int num = 4562; printf("Reverse of no. is %d", reversDigits(num)); getchar(); return 0; }

Time Complexity: O(Log(n)) where n is the input number.

RECURSIVE WAY Thanks to Raj for adding this to the original post.
#include <stdio.h>; /* Recursive function to reverse digits of num*/ int reversDigits(int num) { static int rev_num = 0; static int base_pos = 1; if(num > 0) { reversDigits(num/10); rev_num += (num%10)*base_pos; base_pos *= 10; } return rev_num; } /*Driver program to test reversDigits*/ int main() { int num = 4562; printf("Reverse of no. is %d", reversDigits(num)); getchar(); return 0; }

Time Complexity: O(Log(n)) where n is the input number Note that above above program doesnt consider leading zeroes. For example, for 100 program will print 1. If you want to print 001 then see this comment from Maheshwar. Try extensions of above functions that should also work for floating point numbers.

Efficient way to multiply with 7


May 30, 2009

We can multiply a number by 7 using bitwise operator. First left shift the number by 3 bits (you will get 8n) then subtract the original numberfrom the shifted number and return the difference (8n n).

Program:
# include<stdio.h> int multiplyBySeven(unsigned int n) { /* Note the inner bracket here. This is needed because precedence of '-' operator is higher than '<<' */ return ((n<<3) - n); } /* Driver program to test above function */ int main() { unsigned int n = 4; printf("%u", multiplyBySeven(n)); getchar(); return 0; }

Time Complexity: O(1) Space Complexity: O(1) Note: Works only for positive integers. Same concept can be used for fast multiplication by 9 or other numbers.

Write one line C function to find whether a no is power of two

May 30, 2009

1. A simple method for this is to simply take the log of the number on base 2 and if you get an integer then number is power of 2. 2. Another solution is to keep dividing the number by two, i.e, do n = n/2 iteratively. In any iteration, if n%2 becomes non-zero and n is not 1 then n is not a power of 2. If n becomes 1 then it is a power of 2.
#include<stdio.h> #define bool int /* Function to check if x is power of 2*/ bool isPowerOfTwo(int n) { if(n == 0) return 0; while(n != 1) { n = n/2; if(n%2 != 0 && n != 1) return 0; } return 1; } /*Driver program to test above function*/ int main() { int test_no = 31; if(isPowerOfTwo(test_no)) printf("%d is a power of 2", test_no); else printf("%d is not a power of 2", test_no); getchar(); }

3. All power of two numbers have only one bit set. So count the no. of set bits and if you get 1 then number is a power of 2. Please see http://geeksforgeeks.org/?p=1176 for counting set bits. 4. If we subtract a power of 2 numbers by 1 then all unset bits after the only set bit become set; and the set bit become unset. For example for 4 ( 100) and 16(10000), we get following after subtracting 1 3 > 011 15 > 01111

So, if a number n is a power of 2 then bitwise & of n and n-1 will be zero. We can say n is a power of 2 or not based on value of n&(n-1). The expression n&(n-1) will not work when n is 0. To handle this case also, our expression will become n& (!n&(n-1)) (thanks to Mohammad for adding this case). Below is the implementation of this method.
#include<stdio.h> #define bool int /* Function to check if x is power of 2*/ bool isPowerOfTwo (int x) { /* First x in the below expression is for the case when x is 0 */ return x && (!(x&(x-1))); } /*Driver program to test above function*/ int main() { int test_no = 15; if(isPowerOfTwo(test_no)) printf("%d is a power of 2", test_no); else printf("%d is not a power of 2", test_no); getchar(); }

Position of rightmost set bit


June 19, 2009

Write a one line C function to return position of first 1 from right to left, in binary representation of an Integer.

I/P O/P I/P O/P

18, 2 19, 1

Binary Representation 010010 Binary Representation 010011

Let I/P be 12 (1100)

Algorithm: (Example 18(010010)) 1. Take two's complement of the given no as all bits are reverted except the first '1' from right to left (10111)

2 Do an bit-wise & with original no, this will return no with the required one only (00010) 3 Take the log2 of the no, you will get position -1 (1) 4 Add 1 (2)

Program:
#include<stdio.h> #include<math.h> unsigned int getFirstSetBitPos(int n) { return log2(n&-n)+1; } int main() { int n = 12; printf("%u", getFirstSetBitPos(n)); getchar(); return 0; }

Print reverse of a string using recursion


June 19, 2009

Write a recursive C function to print reverse of a given string. Program:


# include <stdio.h> /* Function to print reverse of the passed string */ void reverse(char *str) { if(*str) { reverse(str+1); printf("%c", *str); } } /* Driver program to test above function */ int main() { char a[] = "Geeks for Geeks"; reverse(a); getchar();

return 0; }

Explanation: Recursive function (reverse) takes string pointer (str) as input and calls itself with next location to passed pointer (str+1). Recursion continues this way, when pointer reaches \0, all functions accumulated in stack print char at passed location (str) and return one by one. Time Complexity: O(n)

Find the Number Occurring Odd Number of Times


June 22, 2009

Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time & constant space. Example: I/P = [1, 2, 3, 2, 3, 1, 3] O/P = 3 Algorithm: Do bitwise XOR of all the elements. Finally we get the number which has odd occurrences.

Program:
#include <stdio.h> int getOddOccurrence(int ar[], int ar_size) { int i; int res = 0; for (i=0; i < ar_size; i++) res = res ^ ar[i]; return res; } /* Diver function to test above function */ int main() { int ar[] = {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2}; int n = sizeof(ar)/sizeof(ar[0]);

printf("%d", getOddOccurrence(ar, n)); return 0; }

Time Complexity: O(n)

Largest Sum Contiguous Subarray


June 22, 2009

Write an efficient C program to find the sum of contiguous subarray within a one-dimensional array of numbers which has the largest sum. Kadanes Algorithm:

Initialize: max_so_far = 0 max_ending_here = 0 Loop for each element of the array (a) max_ending_here = max_ending_here + a[i] (b) if(max_ending_here < 0) max_ending_here = 0 (c) if(max_so_far < max_ending_here) max_so_far = max_ending_here return max_so_far
Explanation: Simple idea of the Kadane's algorithm is to look for all positive contiguous segments of the array (max_ending_here is used for this). And keep track of maximum sum contiguous segment among all positive segments (max_so_far is used for this). Each time we get a positive sum compare it with max_so_far and update max_so_far if it is greater than max_so_far Lets take the example: {-2, -3, 4, -1, -2, 1, 5, -3} max_so_far = max_ending_here = 0

for i=0, a[0] = -2 max_ending_here = max_ending_here + (-2) Set max_ending_here = 0 because max_ending_here < 0 for i=1, a[1] = -3 max_ending_here = max_ending_here + (-3) Set max_ending_here = 0 because max_ending_here < 0 for i=2, a[2] = 4 max_ending_here = max_ending_here + (4) max_ending_here = 4 max_so_far is updated to 4 because max_ending_here greater than max_so_far which was 0 till now for i=3, a[3] = -1 max_ending_here = max_ending_here + (-1) max_ending_here = 3 for i=4, a[4] = -2 max_ending_here = max_ending_here + (-2) max_ending_here = 1 for i=5, a[5] = 1 max_ending_here = max_ending_here + (1) max_ending_here = 2 for i=6, a[6] = 5 max_ending_here = max_ending_here + (5) max_ending_here = 7 max_so_far is updated to 7 because max_ending_here is greater than max_so_far for i=7, a[7] = -3 max_ending_here = max_ending_here + (-3) max_ending_here = 4 Program:
#include<stdio.h> int maxSubArraySum(int a[], int size) { int max_so_far = 0, max_ending_here = 0;

int i; for(i = 0; i < size; i++) { max_ending_here = max_ending_here + a[i]; if(max_ending_here < 0) max_ending_here = 0; if(max_so_far < max_ending_here) max_so_far = max_ending_here; } return max_so_far; } /*Driver program to test maxSubArraySum*/ int main() { int a[] = {-2, -3, 4, -1, -2, 1, 5, -3}; int n = sizeof(a)/sizeof(a[0]); int max_sum = maxSubArraySum(a, n); printf("Maximum contiguous sum is %d\n", max_sum); getchar(); return 0; }

Notes: Algorithm doesn't work for all negative numbers. It simply returns 0 if all numbers are negative. For handling this we can add an extra phase before actual implementation. The phase will look if all numbers are negative, if they are it will return maximum of them (or smallest in terms of absolute value). There may be other ways to handle it though. Above program can be optimized further, if we compare max_so_far with max_ending_here only if max_ending_here is greater than 0.
int maxSubArraySum(int a[], int size) { int max_so_far = 0, max_ending_here = 0; int i; for(i = 0; i < size; i++) { max_ending_here = max_ending_here + a[i]; if(max_ending_here < 0) max_ending_here = 0; /* Do not compare for all elements. Compare only when max_ending_here > 0 */ else if (max_so_far < max_ending_here) max_so_far = max_ending_here; } return max_so_far; }

Time Complexity: O(n) Algorithmic Paradigm: Dynamic Programming Now try below question Given an array of integers (possibly some of the elements negative), write a C program to find out the *maximum product* possible by adding 'n' consecutive integers in the array, n <= ARRAY_SIZE. Also give where in the array this sequence of n integers starts. References: http://en.wikipedia.org/wiki/Kadane%27s_Algorithm

Implement Your Own sizeof


June 22, 2009

Here is an implementation.
#define my_sizeof(type) (char *)(&type+1)-(char*)(&type) int main() { double x; printf("%d", my_sizeof(x)); getchar(); return 0; }

You can also implement using function instead of macro, but function implementation cannot be done in C as C doesnt support function overloading and sizeof() is supposed to receive parameters of all data types. Note that above implementation assumes that size of character is one byte. Time Complexity: O(1) Space Complexity: O(1)

Find the Missing Number


June 22, 2009

You are given a list of n-1 integers and these integers are in the range of 1 to n. There are no duplicates in list. One of the integers is missing in the list. Write an efficient code to find the missing integer.

Example: I/P [1, 2, 4, ,6, 3, 7, 8] O/P 5

METHOD 1(Use sum formula) Algorithm:

1. Get the sum of numbers total = n*(n+1)/2 2 Subtract all the numbers from sum and you will get the missing number.
Program:
#include<stdio.h> /* getMissingNo takes array and size of array as arguments*/ int getMissingNo (int a[], int n) { int i, total; total = (n+1)*(n+2)/2; for ( i = 0; i< n; i++) total -= a[i]; return total; } /*program to test above function */ int main() { int a[] = {1,2,4,5,6}; int miss = getMissingNo(a,5); printf("%d", miss); getchar(); }

Time Complexity: O(n)

METHOD 2(Use XOR)

1) XOR all the array elements, let the result of XOR be X1. 2) XOR all numbers from 1 to n, let XOR be X2.

3) XOR of X1 and X2 gives the missing number.


#include<stdio.h> /* getMissingNo takes array and size of array as arguments*/ int getMissingNo(int a[], int n) { int i; int x1 = a[0]; /* For xor of all the elemets in arary */ int x2 = 1; /* For xor of all the elemets from 1 to n+1 */ for (i = 1; i< n; i++) x1 = x1^a[i]; for ( i = 2; i <= n+1; i++) x2 = x2^i; return (x1^x2); } /*program to test above function */ int main() { int a[] = {1, 2, 4, 5, 6}; int miss = getMissingNo(a, 5); printf("%d", miss); getchar(); }

Time Complexity: O(n) In method 1, if the sum of the numbers goes beyond maximum allowed integer, then there can be integer overflow and we may not get correct answer. Method 2 has no such problems.

Power Set
June 22, 2009

Power Set Power set P(S) of a set S is the set of all subsets of S. For example S = {a, b, c} then P(s) = {{}, {a}, {b}, {c}, {a,b}, {a, c}, {b, c}, {a, b, c}}. If S has n elements in it then P(s) will have 2^n elements

Algorithm:

Input: Set[], set_size 1. Get the size of power set powet_set_size = pow(2, set_size)

Loop for counter from 0 to pow_set_size (a) Loop for i = 0 to set_size (i) If ith bit in counter is set Print ith element from set for this subset (b) Print seperator for subsets i.e., newline
Example:

Set = [a,b,c] power_set_size = pow(2, 3) = 8 Run for binary counter = 000 to 111 Value of Counter 000 001 011 100 101 110 111
Program:
#include <stdio.h> #include <math.h> void printPowerSet(char *set, int set_size) { /*set_size of power set of a set with set_size n is (2**n -1)*/ unsigned int pow_set_size = pow(2, set_size); int counter, j; /*Run from counter 000..0 to 111..1*/ for(counter = 0; counter < pow_set_size; counter++) { for(j = 0; j < set_size; j++) { /* Check if jth bit in the counter is set If set then pront jth element from set */ if(counter & (1<<j)) printf("%c", set[j]); } printf("\n"); }

Subset -> Empty set -> a -> ab -> c -> ac -> bc -> abc

} /*Driver program to test printPowerSet*/ int main() { char set[] = {'a','b','c'}; printPowerSet(set, 3); getchar(); return 0; }

Time Complexity: O(n2^n) There are more efficient ways of doing this. Will update here soon with more efficient method. References: http://en.wikipedia.org/wiki/Power_set

Condition To Print HelloWord


June 22, 2009

What should be the condition so that the following code snippet prints both HelloWorld !

if else

"condition" printf ("Hello"); printf("World");

Solution:
#include<stdio.h> int main() { if(!printf("Hello")) printf("Hello"); else printf("World"); getchar(); }

Explanation: Printf returns the number of character it has printed successfully. So, following solutions will also work if (printf(Hello) < 0) or if (printf(Hello) < 1) etc

Please comment if you find more solutions of this.

Change/add only one character and print * exactly 20 times


June 22, 2009

In the below code, change/add only one character and print * exactly 20 times.

int main() { int i, n = 20; for (i = 0; i < n; i--) printf("*"); getchar(); return 0; }
Solutions: 1. Replace i by n in for loop's third expression
#include <stdio.h> int main() { int i, n = 20; for (i = 0; i < n; n--) printf("*"); getchar(); return 0; }

2. Put '-' before i in for loop's second expression


#include <stdio.h> int main() { int i, n = 20; for (i = 0; -i < n; i--) printf("*"); getchar(); return 0; }

3. Replace < by + in for loop's second expression


#include <stdio.h> int main()

{ int i, n = 20; for (i = 0; i + n; i--) printf("*"); getchar(); return 0; }

Let's extend the problem little. Change/add only one character and print '*' exactly 21 times. Solution: Put negation operator before i in for loop's second expression. Explanation: Negation operator converts the number into its one's complement.

No. One's complement 0 (00000..00) -1 (1111..11) -1 (11..1111) 0 (00..0000) -2 (11..1110) 1 (00..0001) -3 (11..1101) 2 (00..0010) ............................................... -20 (11..01100) 19 (00..10011)
#include <stdio.h> int main() { int i, n = 20; for (i = 0; ~i < n; i--) printf("*"); getchar(); return 0; }

Please comment if you find more solutions of above problems.

8 queen problem
June 22, 2009

The eight queens problem is the problem of placing eight queens on an 88 chessboard such that none of them attack one another (no two are in the same row, column, or diagonal). More generally, the n queens problem places n queens on an nn chessboard. There are different solutions for the problem.

You can find detailed solutions at http://en.literateprograms.org/Eight_queens_puzzle_(C)

Tree Traversals
June 23, 2009

Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which have only one logical way to traverse them, trees can be traversed in different ways. Following are the generally used ways for traversing trees.

Example Tree

Depth First Traversals: (a) Inorder (b) Preorder (c) Postorder Breadth First or Level Order Traversal Please see this post for Breadth First Traversal. Inorder Traversal:

Algorithm Inorder(tree) 1. Traverse the left subtree, i.e., call Inorder(left-subtree) 2. Visit the root. 3. Traverse the right subtree, i.e., call Inorder(right-subtree)
Uses of Inorder In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order. To get nodes of BST in non-increasing order, a

variation of Inorder traversal where Inorder itraversal s reversed, can be used. Example: Inorder traversal for the above given figure is 4 2 5 1 3. Preorder Traversal:

Algorithm Preorder(tree) 1. Visit the root. 2. Traverse the left subtree, i.e., call Preorder(left-subtree) 3. Traverse the right subtree, i.e., call Preorder(right-subtree)
Uses of Preorder Preorder traversal is used to create a copy of the tree. Preorder traversal is also used to get prefix expression on of an expression tree. Please see http://en.wikipedia.org/wiki/Polish_notation to know why prefix expressions are useful. Example: Preorder traversal for the above given figure is 1 2 4 5 3. Postorder Traversal:

Algorithm Postorder(tree) 1. Traverse the left subtree, i.e., call Postorder(left-subtree) 2. Traverse the right subtree, i.e., call Postorder(right-subtree) 3. Visit the root.
Uses of Postorder Postorder traversal is used to delete the tree. Please see the question for deletion of tree for details. Postorder traversal is also useful to get the postfix expression of an expression tree. Please seehttp://en.wikipedia.org/wiki/Reverse_Polish_notation to for the usage of postfix expression. Example: Postorder traversal for the above given figure is 4 5 2 3 1.
#include <stdio.h> #include <stdlib.h>

/* A binary tree and a pointer struct node { int data; struct node* struct node* };

node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } /* Given a binary tree, print its nodes according to the "bottom-up" postorder traversal. */ void printPostorder(struct node* node) { if (node == NULL) return; // first recur on left subtree printPostorder(node->left); // then recur on right subtree printPostorder(node->right); // now deal with the node printf("%d ", node->data); } /* Given a binary tree, print its nodes in inorder*/ void printInorder(struct node* node) { if (node == NULL) return; /* first recur on left child */ printInorder(node->left); /* then print the data of node */ printf("%d ", node->data); /* now recur on right child */ printInorder(node->right); } /* Given a binary tree, print its nodes in inorder*/ void printPreorder(struct node* node)

{ if (node == NULL) return; /* first print data of node */ printf("%d ", node->data); /* then recur on left sutree */ printPreorder(node->left); /* now recur on right subtree */ printPreorder(node->right); } /* Driver program to test above functions*/ int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); printf("\n Preorder traversal of binary tree is \n"); printPreorder(root); printf("\n Inorder traversal of binary tree is \n"); printInorder(root); printf("\n Postorder traversal of binary tree is \n"); printPostorder(root); getchar(); return 0; }

Time Complexity: O(n) Let us prove it: Complexity function T(n) for all problem where tree traversal is involved can be defined as: T(n) = T(k) + T(n k 1) + c Where k is the number of nodes on one side of root and n-k-1 on the other side. Lets do analysis of boundary conditions

Case 1: Skewed tree (One of the subtrees is empty and other subtree is non-empty ) k is 0 in this case. T(n) = T(0) + T(n-1) + c T(n) = 2T(0) + T(n-2) + 2c T(n) = 3T(0) + T(n-3) + 3c T(n) = 4T(0) + T(n-4) + 4c . T(n) = (n-1)T(0) + T(1) + (n-1)c T(n) = nT(0) + (n)c Value of T(0) will be some constant say d. (traversing a empty tree will take some constants time) T(n) = n(c+d) T(n) = (-)(n) (Theta of n) Case 2: Both left and right subtrees have equal number of nodes. T(n) = 2T(|_n/2_|) + c This recursive function is in the standard form (T(n) = aT(n/b) + (-)(n) ) for master methodhttp://en.wikipedia.org/wiki/Master_theorem. If we solve it by master method we get (-)(n) Auxiliary Space : If we dont consider size of stack for function calls then O(1) otherwise O(n).

Write a C program to Calculate Size of a tree


June 23, 2009

Size of a tree is the number of elements present in the tree. Size of the below tree is 5.

Example Tree

Size() function recursively calculates the size of a tree. It works as follows: Size of a tree = Size of left subtree + 1 + Size of right subtree Algorithm:

size(tree) 1. If tree is empty then return 0 2. Else (a) Get the size of left subtree recursively i.e., call size( tree->left-subtree) (a) Get the size of right subtree recursively i.e., call size( tree->right-subtree) (c) Calculate size of the tree as following: tree_size = size(left-subtree) + size(rightsubtree) + 1 (d) Return tree_size
#include <stdio.h> #include <stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */

struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } /* Computes the number of nodes in a tree. */ int size(struct node* node) { if (node==NULL) return 0; else return(size(node->left) + 1 + size(node->right)); } /* Driver program to test size function*/ int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); printf("Size of the tree is %d", size(root)); getchar(); return 0; }

Time & Space Complexities: Since this program is similar to traversal of tree, time and space complexities will be same as Tree traversal (Please see our Tree Traversal post for details)

Write C Code to Determine if Two Trees are Identical


June 26, 2009

Two trees are identical when they have same data and arrangement of data is also same.

To identify if two trees are identical, we need to traverse both trees simultaneously, and while traversing we need to compare data and children of the trees. Algorithm:

sameTree(tree1, tree2) 1. If both trees are empty then return 1. 2. Else If both trees are non -empty (a) Check data of the root nodes (tree1>data == tree2->data) (b) Check left subtrees recursively i.e., call sameTree( tree1->left_subtree, tree2>left_subtree) (c) Check right subtrees recursively i.e., call sameTree( tree1->right_subtree, tree2>right_subtree) (d) If a,b and c are true then return 1. 3 Else return 0 (one is empty and other is not)
#include <stdio.h> #include <stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } /* Given two trees, return true if they are structurally identical */ int identicalTrees(struct node* a, struct node* b) { /*1. both empty */ if (a==NULL && b==NULL) return 1; /* 2. both non-empty -> compare them */

else if (a!=NULL && b!=NULL) { return ( a->data == b->data && identicalTrees(a->left, b->left) && identicalTrees(a->right, b->right) ); } /* 3. one empty, one not -> false */ else return 0; } /* Driver program to test identicalTrees function*/ int main() { struct node *root1 = newNode(1); struct node *root2 = newNode(1); root1->left = newNode(2); root1->right = newNode(3); root1->left->left = newNode(4); root1->left->right = newNode(5); root2->left = newNode(2); root2->right = newNode(3); root2->left->left = newNode(4); root2->left->right = newNode(5); if(identicalTrees(root1, root2)) printf("Both tree are identical."); else printf("Trees are not identical."); getchar(); return 0; }

Time Complexity: Complexity of the identicalTree() will be according to the tree with lesser number of nodes. Let number of nodes in two trees be m and n then complexity of sameTree() is O(m) where m < n.

Write a C Program to Find the Maximum Depth or Height of a Tree


June 27, 2009

Maximum depth or height of the below tree is 3.

Example Tree

Recursively calculate height of left and right subtrees of a node and assign height to the node as max of the heights of two children plus 1. See below pseudo code and program for details. Algorithm:

maxDepth() 1. If tree is empty then return 0 2. Else (a) Get the max depth of left subtree recursively i.e., call maxDepth( tree->left-subtree) (a) Get the max depth of right subtree recursively i.e., call maxDepth( tree->right-subtree) (c) Get the max of max depths of left and right subtrees and add 1 to it for the current node. max_depth = max(max dept of left subtree, max depth of right subtree) + 1 (d) Return max_depth
See the below diagram for more clarity about execution of the recursive function maxDepth() for above example tree.

maxDepth('1') = max(maxDepth('2'), maxDepth('3')) + 1

= 2 + 1 / \ / / / / \ maxDepth('1') maxDepth('3') = 1 = max(maxDepth('4'), maxDepth('5')) + 1 = 1 + 1 = 2 / \ / \ / \ / \ / \ maxDepth('4') = 1 maxDepth('5') = 1


Implementation:
#include<stdio.h> #include<stdlib.h>

\ \ \

/* A binary tree and a pointer struct node { int data; struct node* struct node* };

node has data, pointer to left child to right child */

left; right;

/* Compute the "maxDepth" of a tree -- the number of nodes along the longest path from the root node down to the farthest leaf node.*/ int maxDepth(struct node* node) { if (node==NULL) return 0; else { /* compute the depth of each subtree */ int lDepth = maxDepth(node->left); int rDepth = maxDepth(node->right); /* use the larger one */ if (lDepth > rDepth) return(lDepth+1);

else return(rDepth+1); } } /* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); printf("Hight of tree is %d", maxDepth(root)); getchar(); return 0; }

Time Complexity: O(n) (Please see our post Tree Traversal for details) References: http://cslibrary.stanford.edu/110/BinaryTrees.html

Write a C program to Delete a Tree.


June 27, 2009

To delete a tree we must traverse all the nodes of the tree and delete them one by one. So which traversal we should use Inorder or Preorder or Postorder. Answer is simple Postorder, because before deleting the parent node we should delete its children nodes first We can delete tree with other traversals also with extra space complexity but why should we go for other traversals if we have

Postorder available which does the work without storing anything in same time complexity. For the following tree nodes are deleted in order 4, 5, 2, 3, 1

Example Tree

Program
#include<stdio.h> #include<stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } /* This function traverses tree in post order to to delete each and every node of the tree */ void deleteTree(struct node* node) { if (node == NULL) return; /* first delete both subtrees */ deleteTree(node->left); deleteTree(node->right); /* then delete the node */ printf("\n Deleting node: %d", node->data);

free(node); }

/* Driver program to test deleteTree function*/ int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); deleteTree(root); root = NULL; printf("\n Tree deleted "); getchar(); return 0; }

The above deleteTree() function deletes the tree, but doesnt change root to NULL which may cause problems if the user of deleteTree() doesnt change root to NULL and tires to access values using root pointer. We can modify the deleteTree() function to take reference to the root node so that this problem doesnt occur. See the following code.
#include<stdio.h> #include<stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); } /* This function is same as deleteTree() in the previous program */

void _deleteTree(struct node* node) { if (node == NULL) return; /* first delete both subtrees */ _deleteTree(node->left); _deleteTree(node->right); /* then delete the node */ printf("\n Deleting node: %d", node->data); free(node); } /* Deletes a tree and sets the root as NULL */ void deleteTree(struct node** node_ref) { _deleteTree(*node_ref); *node_ref = NULL; } /* Driver program to test deleteTree function*/ int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); // Note that we pass the address of root here deleteTree(&root); printf("\n Tree deleted "); getchar(); return 0; }

Time Complexity: O(n) Space Complexity: If we dont consider size of stack for function calls then O(1) otherwise O(n)

Write an Efficient C Function to Convert a Binary Tree into its Mirror Tree
June 27, 2009

Mirror of a Tree: Mirror of a Binary Tree T is another Binary Tree M(T) with left and right children of all non-leaf nodes interchanged.

Trees in the below figure are mirror of each other Algorithm - Mirror(tree):

(1) Call Mirror for left-subtree i.e., Mirror(left-subtree) (2) Call Mirror for right-subtree i.e., Mirror(left-subtree) (3) Swap left and right subtrees. temp = left-subtree left-subtree = right-subtree right-subtree = temp
Program:
#include<stdio.h> #include<stdlib.h> /* A binary tree and a pointer struct node { int data; struct node* struct node* }; node has data, pointer to left child to right child */

left; right;

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL; return(node); }

/* Change a tree so that the roles of the left and right pointers are swapped at every node. So the tree... 4 / \ 2 5 / \ 1 3 is changed to... 4 / \ 5 2 / \ 3 1 */ void mirror(struct node* node) { if (node==NULL) return; else { struct node* temp; /* do the subtrees */ mirror(node->left); mirror(node->right); /* swap the temp node->left node->right } } pointers in this node */ = node->left; = node->right; = temp;

/* Helper function to test mirror(). Given a binary search tree, print out its data elements in increasing sorted order.*/ void inOrder(struct node* node) { if (node == NULL) return; inOrder(node->left); printf("%d ", node->data); inOrder(node->right); }

/* Driver program to test mirror() */ int main() { struct node *root = newNode(1); root->left = newNode(2); root->right = newNode(3);

root->left->left = newNode(4); root->left->right = newNode(5); /* Print inorder traversal of the input tree */ printf("\n Inorder traversal of the constructed tree is \n"); inOrder(root); /* Convert tree to its mirror */ mirror(root); /* Print inorder traversal of the mirror tree */ printf("\n Inorder traversal of the mirror tree is \n"); inOrder(root); getchar(); return 0; }

Time & Space Complexities: This program is similar to traversal of tree space and time complexities will be same as Tree traversal (Please see our Tree Traversal post for details)

Output of C Programs | Set 1


June 27, 2009

Predict the output of below programs. Question 1


#include<stdio.h> int main() { int n; for(n = 7; n!=0; n--) printf("n = %d", n--); getchar(); return 0; }

Output:Above program goes in infinite loop because n is never zero when loop condition (n != 0) is checked. Question 2
#include<stdio.h> int main() { printf("%x", -1<<1); getchar(); return 0; }

Output is dependent on the compiler. For 32 bit compiler it would be fffffffe and for 16 bit it would be fffe. Question 3
# include <stdio.h> # define scanf main() { printf(scanf, scanf); getchar(); return 0; } "%s Geeks For Geeks "

Output: %s Geeks For Geeks Geeks For Geeks Explanation: After pre-processing phase of compilation, printf statement will become.

printf("%s Geeks For Geeks ", Geeks ");

"%s Geeks For

Now you can easily guess why output is %s Geeks For Geeks Geeks For Geeks.

Question 4
#include <stdlib.h> #include <stdio.h> enum {false, true}; int main() { int i = 1; do { printf("%d\n", i); i++; if (i < 15) continue; } while (false);

getchar(); return 0; }

Output: 1 Explanation: The do wile loop checks condition after each iteration. So after continue statement, control transfers to the statement while(false). Since the condition is false i is printed only once. Now try below program.
#include <stdlib.h> #include <stdio.h> enum {false, true}; int main() { int i = 1;

do { printf("%d\n", i); i++; if (i < 15) break; } while (true);

getchar(); return 0; }

Question 5
char *getString() { char *str = "Nice test for strings"; return str; }

int main() { printf("%s", getString()); getchar(); return 0; }

Output: Nice test for strings The above program works because string constants are stored in Data Section (not in Stack Section). So, when getString returns *str is not lost.

Output of C Programs | Set 2


June 29, 2009

Predict the output of below programs. Question 1


char *getString() { char str[] = "Will I be printed?"; return str; } int main() { printf("%s", getString()); getchar(); }

Output: Some garbage value The above program doesnt work because array variables are stored in Stack Section. So, when getString returns values at str are deleted and str becomes dangling pointer. Question 2
int main() { static int i=5; if(--i){ main(); printf("%d ",i); } }

Output: 0 0 0 0 Explanation: Since i is a static variable and is stored in Data Section, all calls to main share same i. Question 3
int main() { static int var = 5; printf("%d ",var--); if(var) main(); }

Output: 5 4 3 2 1 Explanation: Same as previous question. The only difference here is, sequence of calling main and printf is changed, therefore different output. Question 4
int main() { int x; printf("%d",scanf("%d",&x)); /* Suppose that input value given for above scanf is 20 */ return 1; }

Output: 1 scanf returns the no. of inputs it has successfully read. Question 5
# include <stdio.h>

int main() { int i=0; for(i=0; i<20; i++) { switch(i) { case 0: i+=5; case 1: i+=2; case 5: i+=5; default: i+=4; break; } printf("%d } ", i);

getchar(); return 0; }

Output: 16 21 Explanation: Initially i = 0. Since case 0 is true i becomes 5, and since there is no break statement till last statement of switch block, i becomes 16. Now in next iteration no case is true, so execution goes to default and i becomes 21.

In C, if one case is true switch block is executed until it finds break statement. If no break statement is present all cases are executed after the true case. If you want to know why switch is implemented like this, well this implementation is useful for situations like below.

switch (c) { case 'a': case 'e': case 'i' : case 'o': case 'u': printf(" Vowel character"); break; default : printf("Not a Vowel character");; break; } Output of C Programs | Set 3
June 29, 2009

Predict the output of the below program. Question 1


#include <stdio.h> int main() { printf("%d", main); getchar(); return 0; }

Output: Address of function main. Explanation: Name of the function is actually a pointer variable to the function and prints the address of the function. Symbol table is implemented like this.

struct { char *name; int (*funcptr)(); } symtab[] = { "func", func, "anotherfunc", anotherfunc, };
Question 2
#include <stdio.h> int main() { printf("\new_c_question\by"); printf("\rgeeksforgeeks");

getchar(); return 0; }

Output: geeksforgeeksl Explanation: First printf prints ew_c_questioy. Second printf has \r in it so it goes back to start of the line and starts printing characters. Now try to print following without using any of the escape characters.

new c questions by geeksforgeeks


Question 3
# include<stdio.h> # include<stdlib.h>

void fun(int *a) { a = (int*)malloc(sizeof(int)); }

int main() { int *p; fun(p); *p = 6; printf("%d\n",*p);

getchar(); return(0); }

It does not work. Try replacing int *p; with int *p = NULL; and it will try to dereference a null pointer. This is because fun() makes a copy of the pointer, so when malloc() is called, it is setting the copied pointer to the memory location, not p. p is pointing to random memory before and after the call to fun(), and when you dereference it, it will crash. If you want to add memory to a pointer from a function, you need to pass the address of the pointer (ie. double pointer). Thanks to John Doe for providing the correct solution. Question 4
#include <stdio.h> int main() {

int i; i = 1, 2, 3; printf("i = %d\n", i);

getchar(); return 0; }

Output: 1 The above program prints 1. Associativity of comma operator is from left to right, but = operator has higher precedence than comma operator. Therefore the statement i = 1, 2, 3 is treated as (i = 1), 2, 3 by the compiler. Now it should be easy to tell output of below program.
#include <stdio.h> int main() { int i; i = (1, 2, 3); printf("i = %d\n", i);

getchar(); return 0; }

Question 5
#include <stdio.h> int main() {

int first = 50, second = 60, third; third = first /* Will this comment work? */ + second; printf("%d /* And this? */ \n", third);

getchar(); return 0; }

Output: 110 /* And this? */ Explanation: Compiler removes everything between /* and */ if they are not present inside double quotes ().

Check for Integer Overflow


June 29, 2009

Write a C function, int addOvf(int* result, int a, int b) If there is no overflow, the function places the resultant = sum a+b in result and returns 0. Otherwise it returns -1. The solution of casting to long and adding to find detecting the overflow is not allowed. Method 1 There can be overflow only if signs of two numbers are same, and sign of sum is opposite to the signs of numbers.

1) Calculate sum 2) If both numbers are positive and sum is negative then return -1 Else If both numbers are negative and sum is positive then return -1 Else return 0
#include<stdio.h> #include<stdlib.h>

/* Takes pointer to result and two numbers as arguments. If there is no overflow, the function

places the resultant = sum a+b in result and returns 0, otherwise it returns -1 */ int addOvf(int* result, int a, int b) { *result = a + b; if(a > 0 && b > 0 && *result < 0) return -1; if(a < 0 && b < 0 && *result > 0) return -1; return 0; }

int main() { int *res = (int *)malloc(sizeof(int)); int x = 2147483640; int y = 10;

printf("%d", addOvf(res, x, y));

printf("\n %d", *res); getchar(); return 0; }

Time Complexity : O(1) Space Complexity: O(1)

Method 2

Thanks to Himanshu Aggarwal for adding this method. This method doesnt modify *result if there us an overflow.
#include<stdio.h> #include<limits.h> #include<stdlib.h>

int addOvf(int* result, int a, int b) { if( a > INT_MAX - b) return -1; else { *result = a + b; return 0; } }

int main() { int *res = (int *)malloc(sizeof(int)); int x = 2147483640; int y = 10;

printf("%d", addOvf(res, x, y)); printf("\n %d", *res); getchar(); return 0; }

Time Complexity : O(1) Space Complexity: O(1)

What is the best way in C to convert a number to a string?


June 29, 2009

Solution: Use sprintf() function.


#include<stdio.h> int main() { char result[50]; float num = 23.34; sprintf(result, "%f", num); printf("\n The string for the num is %s", result); getchar(); }

You can also write your own function using ASCII values of numbers.

How will you show memory representation of C variables?


June 30, 2009

Write a C program to show memory representation of C variables like int, float, pointer, etc. Algorithm: Get the address and size of the variable. Typecast the address to char pointer. Now loop for size of the variable and print the value at the typecasted pointer. Program:

#include <stdio.h> typedef unsigned char *byte_pointer; /*show bytes takes byte pointer as an argument

and prints memory contents from byte_pointer to byte_pointer + len */ void show_bytes(byte_pointer start, int len) { int i; for (i = 0; i < len; i++) printf(" %.2x", start[i]); printf("\n"); } void show_int(int x) { show_bytes((byte_pointer) &x, sizeof(int)); } void show_float(float x) { show_bytes((byte_pointer) &x, sizeof(float)); } void show_pointer(void *x) { show_bytes((byte_pointer) &x, sizeof(void *)); } /* Drover program to test above functions */ int main() { int i = 1; float f = 1.0; int *p = &i; show_float(f); show_int(i); show_pointer(p); show_int(i);

getchar(); return 0; } Output of C Programs | Set 4


July 3, 2009

Predict the output of below programs Question 1


#includestdio.h int main() { struct site { char name[] = "GeeksforGeeks"; int no_of_pages = 200; }; struct site *ptr; printf("%d",ptr->no_of_pages); printf("%s",ptr->name); getchar(); return 0; }

Output: Compiler error Explanation: Note the difference between structure/union declaration and variable declaration. When you declare a structure, you actually declare a new data type suitable for your purpose. So you cannot initialize values as it is not a variable declaration but a data type declaration.

Reference: http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/SYN TAX/struct.html Question 2


int main() { char a[2][3][3] = {'g','e','e','k','s','f','o', 'r','g','e','e','k','s'}; printf("%s ", **a); getchar(); return 0; }

Output: geeksforgeeks Explanation: We have created a 3D array that should have 2*3*3 (= 18) elements, but we are initializing only 13 of them. In C when we initialize less no of elements in an array all uninitialized elements become \0 in case of char and 0 in case of integers. Question 3
int main() { char str[]= "geeks\nforgeeks"; char *ptr1, *ptr2;

ptr1 = &str[3]; ptr2 = str + 5; printf("%c", ++*str - --*ptr1 + *ptr2 + 2); printf("%s", str);

getchar(); return 0; }

Output: heejs forgeeks Explanation: Initially ptr1 points to k and ptr2 points to \n in geeks\nforgeeks. In print statement value at str is incremented by 1 and value at ptr1 is decremented by 1. So string becomes heejs\nforgeeks . First print statement becomes printf(%c, h j + n + 2) h j + \n + 2 = -2 + \n + 2 = \n First print statements newline character. and next print statement prints heejs\nforgeeks. Question 4
#include <stdio.h> int fun(int n) { int i, j, sum = 0; for(i = 1;i<=n;i++) for(j=i;j<=i;j++) sum=sum+j; return(sum); }

int main()

{ printf("%d", fun(15)); getchar(); return 0; }

Output: 120 Explanation: fun(n) calculates sum of first n integers or we can say it returns n(n+1)/2. Question 5
#include <stdio.h> int main() { int c = 5, no = 1000; do { no /= c; } while(c--);

printf ("%d\n", no); return 0; }

Output: Exception Divide by zero Explanation: There is a bug in the above program. It goes inside the do-while loop for c = 0 also. Be careful when you are using do-while loop like this!!

Ugly Numbers
July 11, 2009

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence

1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, shows the first 11 ugly numbers. By convention, 1 is included. Write a program to find and print the 150th ugly number.

METHOD 1 (Simple) Thanks to Nedylko Draganov for suggesting this solution. Algorithm: Loop for all positive integers until ugly number count is smaller than n, if an integer is ugly than increment ugly number count. To check if a number is ugly, divide the number by greatest divisible powers of 2, 3 and 5, if the number becomes 1 then it is an ugly number otherwise not. For example, let us see how to check for 300 is ugly or not. Greatest divisible power of 2 is 4, after dividing 300 by 4 we get 75. Greatest divisible power of 3 is 3, after dividing 75 by 3 we get 25. Greatest divisible power of 5 is 25, after dividing 25 by 25 we get 1. Since we get 1 finally, 300 is ugly number. Implementation:
# include<stdio.h> # include<stdlib.h>

/*This function divides a by greatest divisible power of b*/ int maxDivide(int a, int b) { while (a%b == 0) a = a/b; return a; }

/* Function to check if a number is ugly or not */ int isUgly(int no) { no = maxDivide(no, 2); no = maxDivide(no, 3); no = maxDivide(no, 5);

return (no == 1)? 1 : 0; }

/* Function to get the nth ugly number*/ int getNthUglyNo(int n) { int i = 1; int count = 1; /* ugly number count */

/*Check for all integers untill ugly count becomes n*/ while (n > count) { i++; if (isUgly(i)) count++; } return i; }

/* Driver program to test above functions */

int main() { unsigned no = getNthUglyNo(150); printf("150th ugly no. is %d ", getchar(); return 0; } no);

This method is not time efficient as it checks for all integers until ugly number count becomes n, but space complexity of this method is O(1)

METHOD 2 (Use Dynamic Programming) Here is a time efficient solution with O(n) extra space Algorithm:

1 Declare an array for ugly numbers: ugly[150] 2 Initialize first ugly no: ugly[0] = 1 3 Initialize three array index variables i2, i3, i5 to point to 1st element of the ugly array: i2 = i3 = i5 =0; 4 Initialize 3 choices for the next ugly no: next_mulitple_of_2 = ugly[i2]*2; next_mulitple_of_3 = ugly[i3]*3 next_mulitple_of_5 = ugly[i5]*5; 5 Now go in a loop to fill all ugly numbers till 150: For (i = 1; i < 150; i++ ) { /* These small steps are not optimized for good readability. Will optimize them in C program */ next_ugly_no = Min(next_mulitple_of_2,

next_mulitple_of_3, next_mulitple_of_5); if (next_ugly_no == next_mulitple_of_2) { i2 = i2 + 1; next_mulitple_of_2 = ugly[i2]*2; } if (next_ugly_no == next_mulitple_of_3) { i3 = i3 + 1; next_mulitple_of_3 = ugly[i3]*3; } if (next_ugly_no == next_mulitple_of_5) { i5 = i5 + 1; next_mulitple_of_5 = ugly[i5]*5; } ugly[i] = next_ugly_no }/* end of for loop */ 6.return next_ugly_no
Example: Let us see how it works

initialize ugly[] = | 1 | i2 = i3 = i5 = 0; First iteration ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(2, 3, 5) = 2 ugly[] = | 1 | 2 | i2 = 1, i3 = i5 = 0 (i2 got incremented )

Second iteration ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(4, 3, 5) = 3 ugly[] = | 1 | 2 | 3 | i2 = 1, i3 = 1, i5 = 0 (i3 got incremented ) Third iteration ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(4, 6, 5) = 4 ugly[] = | 1 | 2 | 3 | 4 | i2 = 2, i3 = 1, i5 = 0 (i2 got incremented ) Fourth iteration ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(6, 6, 5) = 5 ugly[] = | 1 | 2 | 3 | 4 | 5 | i2 = 2, i3 = 1, i5 = 1 (i5 got incremented ) Fifth iteration ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5) = Min(6, 6, 10) = 6 ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 | i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented ) Will continue same way till I < 150

Program:
# include<stdio.h> # include<stdlib.h> # define bool int

/* Function to find minimum of 3 numbers */ unsigned min(unsigned , unsigned , unsigned );

/* Function to get the nth ugly number*/ unsigned getNthUglyNo(unsigned n) { unsigned *ugly = (unsigned *)(malloc (sizeof(unsigned)*n)); unsigned i2 = 0, i3 = 0, i5 = 0; unsigned i; unsigned next_multiple_of_2 = 2; unsigned next_multiple_of_3 = 3; unsigned next_multiple_of_5 = 5; unsigned next_ugly_no = 1; *(ugly+0) = 1;

for(i=1; i<n; i++) { next_ugly_no = min(next_multiple_of_2, next_multiple_of_3, next_multiple_of_5); *(ugly+i) = next_ugly_no; if(next_ugly_no == next_multiple_of_2) {

i2 = i2+1; next_multiple_of_2 = *(ugly+i2)*2; } if(next_ugly_no == next_multiple_of_3) { i3 = i3+1; next_multiple_of_3 = *(ugly+i3)*3; } if(next_ugly_no == next_multiple_of_5) { i5 = i5+1; next_multiple_of_5 = *(ugly+i5)*5; } } /*End of for loop (i=1; i<n; i++) */ return next_ugly_no; }

/* Function to find minimum of 3 numbers */ unsigned min(unsigned a, unsigned b, unsigned c) { if(a <= b) { if(a <= c) return a; else return c; } if(b <= c) return b; else

return c; }

/* Driver program to test above functions */ int main() { unsigned no = getNthUglyNo(150); printf("%dth ugly no. is %d ", 150, no); getchar(); return 0; }

Algorithmic Paradigm: Dynamic Programming Time Complexity: O(n) Storage Complexity: O(n)

Little and Big Endian Mystery


July 16, 2009

What are these? Little and big endian are two ways of storing multibyte data-types ( int, float, etc). In little endian machines, last byte of binary representation of the multibyte data-type is stored first. On the other hand, in big endian machines, first byte of binary representation of the multibyte data-type is stored first. Suppose integer is stored as 4 bytes (For those who are using DOS based compilers such as C++ 3.0 , integer is 2 bytes) then a variable x with value 001234567 will be stored as following.

Memory representation of integer ox01234567 inside Big and little endian machines

How to see memory representation of multibyte data types on your machine? Here is a sample C code that shows the byte representation of int, float and pointer.
#include <stdio.h>

/* function to show bytes in memory, from location start to start+n*/ void show_mem_rep(char *start, int n) { int i; for (i = 0; i < n; i++) printf(" %.2x", start[i]); printf("\n"); }

/*Main function to call above function for 0x01234567*/ int main() { int i = 0x01234567; show_mem_rep((char *)&i, sizeof(i)); getchar();

return 0; }

When above program is run on little endian machine, gives 67 45 23 01 as output , while if it is run on endian machine, gives 01 23 45 67 as output. Is there a quick way to determine endianness of your machine? There are n no. of ways for determining endianness of your machine. Here is one quick way of doing the same.
#include <stdio.h> int main() { unsigned int i = 1; char *c = (char*)&i; if (*c) printf("Little endian"); else printf("Big endian"); getchar(); return 0; }

In the above program, a character pointer c is pointing to an integer i. Since size of character is 1 byte when the character pointer is dereferenced it will contain only first byte of integer. If machine is little endian then *c will be 1 (because last byte is stored first) and if machine is big endian then *c will be 0. Does endianness matter for programmers? Most of the times compiler takes care of endianness, however, endianness becomes an issue in following cases.

It matters in network programming: Suppose you write integers to file on a little endian machine and you transfer this file to a big endian machine. Unless there is little andian to big endian transformation, big endian machine will read the file in reverse order. You can find such a practical example here. Standard byte order for networks is big endian, also known as network byte order. Before transferring data on network, data is first converted to network byte order (big endian). Sometimes it matters when you are using type casting, below program is an example.
#include <stdio.h> int main() { unsigned char arr[2] = {0x01, 0x00}; unsigned short int x = *(unsigned short int *) arr; printf("%d", x); getchar(); return 0; }

In the above program, a char array is typecasted to an unsigned short integer type. When I run above program on little endian machine, I get 1 as output, while if I run it on a big endian machine I get 256. To make programs endianness independent, above programming style should be avoided. What are bi-endians? Bi-endian processors can run in both modes little and big endian. What are the examples of little, big endian and bi-endian machines ? Intel based processors are little endians. ARM processors were little endians. Current generation ARM processors are bi-endian.

Motorola 68K processors are big endians. PowerPC (by Motorola) and SPARK (by Sun) processors were big endian. Current version of these processors are bi-endians. Does endianness effects file formats? File formats which have 1 byte as a basic unit are independent of endianness e..g., ASCII files . Other file formats use some fixed endianness forrmat e.g, JPEG files are stored in big endian format. Which one is better little endian or big endian The term little and big endian came from Gullivers Travels by Jonathan Swift. Two groups could not agree by which end a egg should be opened -a-the little or the big. Just like the egg issue, there is no technological reason to choose one byte ordering convention over the other, hence the arguments degenerate into bickering about sociopolitical issues. As long as one of the conventions is selected and adhered to consistently, the choice is arbitrary.

Write a C function to print the middle of a given linked list


July 16, 2009

Method 1: Traverse the whole linked list and count the no. of nodes. Now traverse the list again till count/2 and return the node at count/2.

Method 2: Traverse linked list using two pointers. Move one pointer by one and other pointer by two. When the fast pointer reaches end slow pointer will reach middle of the linked list.
#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node {

int data; struct node* next; };

/* Function to get the middle of the linked list*/ void printMiddle(struct node *head) { struct node *slow_ptr = head; struct node *fast_ptr = head;

if(head!=NULL) { while((fast_ptr->next)!=NULL && (fast_ptr->next->next)!=NULL) { fast_ptr = fast_ptr->next->next; slow_ptr = slow_ptr->next; } printf("The middle element is [%d]",slow_ptr->data); } }

void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data

*/

new_node->data

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

push(&head, 20); push(&head, 4); push(&head, 15);

printMiddle(head); return 0; }

Method 3: Initialize mid element as head and initialize a counter as 0. Traverse the list from head, while traversing increment the counter and change mid to mid->next whenever the counter is odd. So the mid will move only half of the total length of the list. Thanks to Narendra Kangralkar for suggesting this method.
#include<stdio.h>

#include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to get the middle of the linked list*/ void printMiddle(struct node *head) { int count = 0; struct node *mid = head;

while (head != NULL) { /* update mid, when 'count' is odd number */ if (count & 1) mid = mid->next;

++count; head = head->next; }

/* if empty list is provided */ if (mid != NULL) printf("\tThe middle element is %d\n\n", mid->data); }

void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

push(&head, 20); push(&head, 4); push(&head, 30);

printMiddle(head);

return 0; }

Nth node from the end of a Linked List


July 17, 2009

Given a Linked List and a number n, write a function that returns the value at the nth node from end of the Linked List. Method 1 (Use length of linked list) 1) Calculate the length of Linked List. Let the length be len. 2) Print the (len n + 1)th node from the begining of the Linked List.
#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to get the nth node from the last of a linked list*/ void printNthFromLast(struct node* head, int n) { int len = 0, i; struct node *temp = head;

// 1) count the number of nodes in Linked List while (temp != NULL) { temp = temp->next;

len++; }

// check if value of n is not more than length of the linked list if (len < n) return;

temp = head;

// 2) get the (n-len+1)th node from the begining for (i = 1; i < len-n+1; i++) temp = temp->next;

printf ("%d", temp->data);

return; }

void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

// create linked 35->15->4->20 push(&head, 20); push(&head, 4); push(&head, 15); push(&head, 35);

printNthFromLast(head, 5); getchar(); return 0; }

Following is a recursive C code for the same method. Thanks to Anuj Bansal for providing following code.
void printNthFromLast(struct node* head, int n) { static int i = 0; if(head == NULL) return; printNthFromLast(head->next, n);

if(++i == n) printf("%d", head->data); }

Time Complexity: O(n) where n is the length of linked list.

Method 2 (Use two pointers) Maintain two pointers reference pointer and main pointer. Initialize both reference and main pointers to head. First move reference pointer to n nodes from head. Now move both pointers one by one until reference pointer reaches end. Now main pointer will point to nth node from the end. Return main pointer. Implementation:
#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to get the nth node from the last of a linked list*/ void printNthFromLast(struct node *head, int n) { struct node *main_ptr = head; struct node *ref_ptr = head;

int count = 0; if(head != NULL) { while( count < n ) { if(ref_ptr == NULL) { printf("%d is greater than the no. of " "nodes in list", n); return; } ref_ptr = ref_ptr->next; count++; } /* End of while*/

while(ref_ptr != NULL) { main_ptr = main_ptr->next; ref_ptr } printf("Node no. %d from last is %d ", n, main_ptr->data); } } = ref_ptr->next;

void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL; push(&head, 20); push(&head, 4); push(&head, 15);

printNthFromLast(head, 3); getchar(); }

Time Complexity: O(n) where n is the length of linked list.

Write a function to delete a Linked List


July 18, 2009

Algorithm: Iterate through the linked list and delete all the nodes one by one. Main point here is not to access next of the current pointer if current pointer is deleted.

Implementation:
#include<stdio.h> #include<stdlib.h> #include<assert.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to delete the entire linked list */ void deleteList(struct node** head_ref) { /* deref head_ref to get the real head */ struct node* current = *head_ref; struct node* next;

while (current != NULL) { next = current->next; free(current); current = next; }

/* deref head_ref to affect the real head back in the caller. */ *head_ref = NULL;

/* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Drier program to test count function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

/* Use push() to construct below list 1->12->1->4->1 */

push(&head, 1); push(&head, 4); push(&head, 1); push(&head, 12); push(&head, 1);

printf("\n Deleting linked list"); deleteList(&head);

printf("\n Linked list deleted"); getchar(); }

Time Complexity: O(n) Space Complexity: O(1)

Write a function to delete a Linked List


July 18, 2009

Algorithm: Iterate through the linked list and delete all the nodes one by one. Main point here is not to access next of the current pointer if current pointer is deleted. Implementation:
#include<stdio.h> #include<stdlib.h> #include<assert.h>

/* Link list node */ struct node { int data;

struct node* next; };

/* Function to delete the entire linked list */ void deleteList(struct node** head_ref) { /* deref head_ref to get the real head */ struct node* current = *head_ref; struct node* next;

while (current != NULL) { next = current->next; free(current); current = next; }

/* deref head_ref to affect the real head back in the caller. */ *head_ref = NULL; }

/* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node =

(struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Drier program to test count function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

/* Use push() to construct below list 1->12->1->4->1 push(&head, 1); push(&head, 4); push(&head, 1); push(&head, 12); push(&head, 1); */

printf("\n Deleting linked list"); deleteList(&head);

printf("\n Linked list deleted"); getchar(); }

Time Complexity: O(n) Space Complexity: O(1)

Write a function that counts the number of times a given int occurs in a Linked List
July 19, 2009

Here is a solution.

Algorithm:

1. Initialize count as zero. 2. Loop through each element of linked list: a) If element data is equal to the passed number then increment the count. 3. Return count.
Implementation:
#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Given a reference (pointer to pointer) to the head

of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Counts the no. of occurences of a node (search_for) in a linked list (head)*/ int count(struct node* head, int search_for) { struct node* current = head; int count = 0; while (current != NULL) { if (current->data == search_for) count++; current = current->next;

} return count; }

/* Drier program to test count function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

/* Use push() to construct below list 1->2->1->3->1 push(&head, 1); push(&head, 3); push(&head, 1); push(&head, 2); push(&head, 1); */

/* Check the count function */ printf("count of 1 is %d", count(head, 1)); getchar(); }

Time Complexity: O(n) Auxiliary Space: O(1)

Understanding extern keyword in C


July 19, 2009

Im sure that this post will be as interesting and informative to C virgins (i.e. beginners) as it will be to those who are well versed in C. So let me start with saying that extern keyword applies to C variables (data objects) and C functions. Basically extern keyword extends the

visibility of the C variables and C functions. Probably thats is the reason why it was named as extern. Though (almost) everyone knows the meaning of declaration and definition of a variable/function yet for the sake of completeness of this post, I would like to clarify them. Declaration of a variable/function simply declares that the variable/function exists somewhere in the program but the memory is not allocated for them. But the declaration of a variable/function serves an important role. And that is the type of the variable/function. Therefore, when a variable is declared, the program knows the data type of that variable. In case of function declaration, the program knows what are the arguments to that functions, their data types, the order of arguments and the return type of the function. So thats all about declaration. Coming to the definition, when we define a variable/function, apart from the role of declaration, it also allocates memory for that variable/function. Therefore, we can think of definition as a super set of declaration. (or declaration as a subset of definition). From this explanation, it should be obvious that a variable/function can be declared any number of times but it can be defined only once. (Remember the basic principle that you cant have two locations of the same variable/function). So thats all about declaration and definition. Now coming back to our main objective: Understanding extern keyword in C. Ive explained the role of declaration/definition because its mandatory to understand them to understand the extern keyword. Let us first take the easy case. Use of extern with C functions. By default, the declaration and definition of a C function have extern prepended with them. It means even though we dont use extern with the declaration/definition of C functions, it is present there. For example, when we write.

int foo(int arg1, char arg2);


Theres an extern present in the beginning which is hidden and the compiler treats it as below.

extern int foo(int arg1, char arg2);

Same is the case with the definition of a C function (Definition of a C function means writing the body of the function). Therefore whenever we define a C function, an extern is present there in the beginning of the function definition. Since the declaration can be done any number of times and definition can be done only once, we can notice that declaration of a function can be added in several C/H files or in a single C/H file several times. But we notice the actual definition of the function only once (i.e. in one file only). And as the extern extends the visibility to the whole program, the functions can be used (called) anywhere in any of the files of the whole program provided the declaration of the function is known. (By knowing the declaration of the function, C compiler knows that the definition of the function exists and it goes ahead to compile the program). So thats all about extern with C functions. Now let us the take the second and final case i.e. use of extern with C variables. I feel that it more interesting and information than the previous case where extern is present by default with C functions. So let me ask the question, how would you declare a C variable without defining it? Many of you would see it trivial but its important question to understand extern with C variables. The answer goes as follows.

extern int var;


Here, an integer type variable called var has been declared (remember no definition i.e. no memory allocation for var so far). And we can do this declaration as many times as needed. (remember that declaration can be done any number of times) So far so good. Now how would you define a variable. Now I agree that it is the most trivial question in programming and the answer is as follows.

int var;
Here, an integer type variable called var has been declared as well as defined. (remember that definition is the super set of declaration). Here the memory for var is also allocated. Now here comes the surprise, when we declared/defined a C function, we saw that an extern was present by default. While defining a function, we can prepend it with extern without any issues. But it is not the case with C

variables. If we put the presence of extern in variable as default then the memory for them will not be allocated ever, they will be declared only. Therefore, we put extern explicitly for C variables when we want to declare them without defining them. Also, as the extern extends the visibility to the whole program, by externing a variable we can use the variables anywhere in the program provided we know the declaration of them and the variable is defined somewhere. Now let us try to understand extern with examples. Example 1:
int var; int main(void) { var = 10; return 0; }

Analysis: This program is compiled successfully. Here var is defined (and declared implicitly) globally. Example 2:
extern int var; int main(void) { return 0; }

Analysis: This program is compiled successfully. Here var is declared only. Notice var is never used so no problems. Example 3:
extern int var; int main(void)

{ var = 10; return 0; }

Analysis: This program throws error in compilation. Because var is declared but not defined anywhere. Essentially, the var isnt allocated any memory. And the program is trying to change the value to 10 of a variable that doesnt exist at all. Example 4:
#include "somefile.h" extern int var; int main(void) { var = 10; return 0; }

Analysis: Supposing that somefile.h has the definition of var. This program will be compiled successfully. Example 5:
extern int var = 0; int main(void) { var = 10; return 0; }

Analysis: Guess this program will work? Well, here comes another surprise from C standards. They say that..if a variable is only declared and an initializer is also provided with that declaration, then the

memory for that variable will be allocated i.e. that variable will be considered as defined. Therefore, as per the C standard, this program will compile successfully and work. So that was a preliminary look at extern keyword in C. Im sure that you want to have some take away from the reading of this post. And I would not disappoint you. In short, we can say 1. Declaration can be done any number of times but definition only once. 2. extern keyword is used to extend the visibility of variables/functions(). 3. Since functions are visible through out the program by default. The use of extern is not needed in function declaration/definition. Its use is redundant. 4. When extern is used with a variable, its only declared not defined. 5. As an exception, when an extern variable is declared with initialization, it is taken as definition of the variable as well.

Output of C Programs | Set 5


July 30, 2009

Predict the output of below programs Question 1


int main() { while(1){ if(printf("%d",printf("%d"))) break; else continue; } return 0;

Output: Cant be predicted Explanation: The condition in while loop is 1 so at first shot it looks infinite loop. Then there are break and continue in the body of the while loop, so it may not be infinite loop. The break statement will be executed if the condition under if is met, otherwise continue will be executed. Since theres no other statements after continue in the while loop, continue doesnt serve any purpose. In fact it is extraneous. So let us see the if condition. If we look carefully, we will notice that the condition of the if will be met always, so break will be executed at the first iteration itself and we will come out of while loop. The reason why the condition of if will be met is printf function. Function printf always returns the no. of bytes it has output. For example, the return value of printf(geeks) will be 5 because printf will output 5 characters here. In our case, the inner printf will be executed first but this printf doesnt have argument for format specifier i.e. %d. It means this printf will print any arbitrary value. But notice that even for any arbirary value, the no. of bytes output by inner printf would be non-zero. And those no. of bytes will work as argument to outer printf. The outer printf will print that many no. of bytes and return non-zero value always. So the condition for if is also true always. Therefore, the while loop be executed only once. As a side note, even without outer printf also, the condition for if is always true. Question 2
int main() { unsigned int i=10; while(i-- >= 0) printf("%u ",i); return 0; }

Output: 9 8 7 6 5 4 3 2 1 0 4294967295 4294967294 (on a machine where int is 4 bytes long) 9 8 7 6 5 4 3 2 1 0 65535 65534 . (on a machine where int is 2 bytes long) Explanation: Let us examine the condition of while loop. It is obvious that as far as the condition of while loop is met, printf will be executed. There are two operators in the condition of while loop: post-decrement operator and comparison operator. From operator precedence, we know that unary operator post-decrement has higher priority than comparison operator. But due to post-decrement property, the value of i will be decremented only after it had been used for comparison. So at the first iteration, the condition is true because 10>=0 and then i is decremented. Therefore 9 will be printed. Similarly the loop continues and the value of i keeps on decrementing. Let us see what what happen when condition of while loop becomes 0 >= 0. At this time, condition is met and i is decremented. Since i is unsigned integer, the roll-over happens and i takes the value of the highest +ve value an unsigned int can take. So i is never negative. Therefore, it becomes infinite while loop. As a side note, if i was signed int, the while loop would have been terminated after printing the highest negative value. Question 3
int main() { int x,y=2,z,a; if ( x = y%2) z =2; a=2; printf("%d %d ",z,x); return 0;

Output: 0 Explanation: This question has some stuff for operator precedence. If the condition of if is met, then z will be initialized to 2 otherwise z will contain garbage value. But the condition of if has two operators: assignment operator and modulus operator. The precedence of modulus is higher than assignment. So y%2 is zero and itll be assigned to x. So the value of x becomes zero which is also the effective condition for if. And therefore, condition of if is false. Question 4
int main() { int a[10]; printf("%d",*a+1-*a+3); return 0; }

Output: 4 Explanation: From operator precedence, de-reference operator has higher priority than addition/subtraction operator. So de-reference will be applied first. Here, a is an array which is not initialized. If we use a, then it will point to the first element of the array. Therefore *a will be the first element of the array. Suppose first element of array is x, then the argument inside printf becomes as follows. Its effective value is 4. x+1x+3=4 Question 5
#define prod(a,b) a*b

int main() { int x=3,y=4; printf("%d",prod(x+2,y-1)); return 0; }

Output: 10 Explanation: This program deals with macros, their side effects and operator precedence. Here prod is a macro which multiplies its two arguments a and b. Let us take a closer look. prod(a, b) = a*b prod(x+2, y-1) = x+2*y-1 = 3+2*4-1 = 3+8-1=10 If the programmer really wanted to multiply x+2 and y-1, he should have put parenthesis around a and b as follows. prod(a,b) = (a)*(b) This type of mistake in macro definition is called macro side-effects.

Output of C Programs | Set 6


July 30, 2009

Predict the output of below programs Question 1


int main() { unsigned int i=65000; while ( i++ != 0 ); printf("%d",i);

return 0; }

Output: 1 Explanation: It should be noticed that theres a semi-colon in the body of while loop. So even though, nothing is done as part of while body, the control will come out of while only if while condition isnt met. In other words, as soon as i inside the condition becomes 0, the condition will become false and while loop would be over. But also notice the postincrement operator in the condition of while. So first i will be compared with 0 and i will be incremented no matter whether condition is met or not. Since i is initialized to 65000, it will keep on incrementing till it reaches highest positive value. After that roll over happens, and the value of i becomes zero. The condition is not met, but i would be incremented i.e. to 1. Then printf will print 1. Question 2
int main() { int i=0; while ( +(+i--) != 0) i-=i++; printf("%d",i); return 0; }

Output: -1 Explanation: Let us first take the condition of while loop. There are several operator there. Unary + operator doesnt do anything. So the simplified condition becomes (i) != 0. So i will be compared with 0 and then

decremented no matter whether condition is true or false. Since i is initialized to 0, the condition of while will be false at the first iteration itself but i will be decremented to -1. The body of while loop will not be executed. And printf will print -1. So it wasnt that scary as it seemed to be! Question 3
int main() { float f=5,g=10; enum{i=10,j=20,k=50}; printf("%d\n",++k); printf("%f\n",f<<2); printf("%lf\n",f%g); printf("%lf\n",fmod(f,g)); return 0; }

Output: Program will not compile and give 3 errors Explanation: Here, i, j and k are inside the enum and therefore, they are like constants. In other words, if want to us 10 anywhere in the program , we can use i instead. In the first printf, the value of i is being modified which is not allowed because its enum constant. In the second printf, left-shift operator is being applied on a float which is also not allowed. Similarly, in the third printf, modulus operator is being applied on float f and g which is also not allowed. Question 4
int main() {

int i=10; void pascal f(int,int,int); f(i++, i++, i++); printf(" %d",i); return 0; } void pascal f(integer :i,integer:j,integer :k) { write(i,j,k); }

Output: Program will give compile-time error Explanation: Compiler specific question. Not all compilers support this. Otherwise, pascal enforces left to right processing of arguments. So even though, the argument processing order can be changed by the use of pascal, we cant use Pascal language routines such as write inside C program. Question 5
void pascal f(int i,int j,int k) { printf("%d %d %d",i, j, k); }

void cdecl f(int i,int j,int k) { printf("%d %d %d",i, j, k); }

main() { int i=10; f(i++,i++,i++); printf(" %d\n",i); i=10; f(i++,i++,i++); printf(" %d",i); }

Output: Compiler specific question. Not all the compilers allow this. Explanation: This question deals with the argument passing mechanism. If we call a function, the order in which the arguments of the function are processed is not governed by C Standard. So one compiler can process the arguments from left to right while the other compiler can process them right to left. Usually, the programs are not affected with this because the arguments of the programs are different. For example if we call funtion fun as fun(i,j), then no matter in which order the arguments are processed, the value of i and j will be consistent. But in this case, we are passing the arguments to function f using the same variable. So the order in which arguments are processed by the function will determine the value of those arguments. cdecl enforces right to left processing of arguments while pascal enforces left to right processing of arguments. So the value of i, j and k inside the first function f will be 10, 11 and 12 respectively while the value of i, j and k inside the second function f will be 12, 11 and 10 respectively.

Given only a pointer to a node to be deleted in a singly linked list, how do you delete it?
August 2, 2009

A simple solution is to traverse the linked list until you find the node you want to delete. But this solution requires pointer to the head node which contradicts the problem statement.

Fast solution is to copy the data from the next node to the node to be deleted and delete the next node. Something like following.

struct node *temp = node_ptr->next; node_ptr->data = temp->data; node_ptr->next = temp->next; free(temp);


Program:
#include<stdio.h> #include<assert.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

void printList(struct node *head) { struct node *temp = head; while(temp != NULL) { printf("%d ", temp->data);

temp = temp->next; } }

void deleteNode(struct node *node_ptr) { struct node *temp = node_ptr->next; node_ptr->data node_ptr->next free(temp); } = temp->data; = temp->next;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

/* Use push() to construct below list 1->12->1->4->1 push(&head, 1); push(&head, 4); push(&head, 1); push(&head, 12); push(&head, 1); */

printf("\n Before deleting \n"); printList(head);

/* I m deleting the head itself. You can check for more cases */ deleteNode(head);

printf("\n After deleting \n"); printList(head); getchar(); }

This solution doesnt work if the node to be deleted is the last node of the list. To make this solution work we can mark the end node as a dummy node. But the programs/functions that are using this function should also be modified.

Try this problem for doubly linked list.

Lets experiment with Networking


August 2, 2009

Most of us have studied Computer Networks in a very abstract manner. In other words, not many of us know how the abstract concepts of layers and packets translate in real life networks such as the Internet. Therefore let us do an experiment and see whether these layers, packets etc. exist in any real network also. So get, set and ready to delve into this wonderful world of practical and experimental Networking! The outline of our experiment is as follows. We will capture some live packets, and to understand what is inside those packets, we will analyze those packets by dissecting them. Sounds surgical? Yup, it is. J To start with, we need to have a PC running Windows XP and connected to the Internet. If you are reading this article online, the chances are high that you have everything ready to experiment. Now lets recall some of the theory stuff that we read in Networking Books. The first thing that almost every book tells us networking architecture is layered; remember that 7 layer OSI protocol stack! So where are these protocol layers? In our experiment, we will use 5 layer Internet Protocol stack so that we can solve the mystery of these layers. We start our experiment by installing Wireshark (earlier known as Ethereal). Wireshark is a Network Protocol Analyzer that can capture and analyze the packets transmitted/received via a Network Interface Card (NIC). [You need to bear with me this acronym because Networking is full of acronymsJ] We install Wireshark from http://www.wireshark.org/download.html (at the time of this writing, the latest Wireshark version is 1.0.3). While installing Wireshark, leave the default settings/options as it is. Now our experimental setup is ready. Run Wireshark and click on the first icon (List the available capture interfaces ). Now we see a pop up window that shows Capture Interfaces. See the snapshots as follows.

The number and types of interfaces shown in Capture Interfaces window can be different for you depending on your PCs configuration. For me it shows two interfaces and my Internet connection is through Broadcom Gigabit Interface. So choose the interface through which your Internet connection is available to you. Now lets click on the Options button of this interface. Now we see a new window named Capture Options. In this window, type port 80 in text field named Capture Filter. See the following snapshot for clarification.

Now we are ready to capture the packets passing through our NIC. By setting the filter to port 80, we have instructed Wireshark to capture only those packets that are because of http traffic (remember that we were always told that the default http port is 80!). Now click on the

Start button on Capture Options window. You may see some packets in Wireshark if any program in your PC is accessing http traffic in the background; lets not focus on that. Now open your browser and try to access http://google.comand now you should be seeing lot many packets getting captured in Wireshark. See the snapshot as follows.

Lets start analyzing the captured packets. First of all, find the first instance of http packet that has GET / HTTP/1.1 in its Info field. In the above snapshot, its shown in blue. If we take a closer look, we see that this packet has the headers of the all the 5 layers of the Internet Protocol stack. Layer 1 It is the Physical layer. Here Frames are shown at the physical layer. Layer 2 It is the Data Link layer. In this packet, we can see that Ethernet II is used as data link layer protocol. We can find the MAC address of the source and destination in this header. Layer 3 It is the Network layer. In this packet, we see that IP is used as Network layer protocol. We can see the source and destination IP in this header. Layer 4 It is the Transport layer. In this packet, TCP is used as Transport layer protocol. We can find the source and destination ports in this header.

Layer 5 It is the Application layer. In this packet, HTTP is used as Application layer protocol. Lets explore one of the layers. Other layers can be explored further in the similar fashion. If we expand the Layer 5 i.e. HTTP header, it looks as follows.

Here we see that Host is mentioned as google.com that is what we tried to access from browser. User Agent field of the HTTP header shows the browser details. In my case, it is Mozilla Firefox as evidenced from this header. Destination IP 64.233.187.99 should be one of the IP addresses assigned to Google server where the web server is hosted. It can be verified using a very handy utility command nslookup. The details of the other fields can be explored in the headers of the HTTP, TCP, IP, Ethernet II protocols. Some of the interesting fields are Differentiated Services Field (also known as QoS field) in IP header, Window size in TCP header etc. So we have seen that all those rhetorical concepts of layers etc. do exist in real networks also. And it sounds interesting when you dissect all the packets that pass through your interface card. By doing so, you can get to know what goes/comes through your PC! The idea of this experiment is to provide a conducive platform so that you can explore your own the exciting world of Networking. So welcome aboard!

Write a C program to print all permutations of a given string


August 2, 2009

A permutation, also called an arrangement number or order, is a rearrangement of the elements of an ordered list S into a one-to-one correspondence with S itself. A string of length n has n! permutation. Source: Mathword(http://mathworld.wolfram.com/Permutation.html) Below are the permutations of string ABC. ABC, ACB, BAC, BCA, CAB, CBA Here is a solution using backtracking.

# include <stdio.h>

/* Function to swap values at two pointers */ void swap (char *x, char *y) { char temp; temp = *x; *x = *y; *y = temp;

/* Function to print permutations of string This function takes three parameters: 1. String 2. Starting index of the string 3. Ending index of the string. */ void permute(char *a, int i, int n) { int j; if (i == n) printf("%s\n", a); else { for (j = i; j <= n; j++) { swap((a+i), (a+j)); permute(a, i+1, n); swap((a+i), (a+j)); //backtrack } } }

/* Driver program to test above functions */ int main() { char a[] = "ABC"; permute(a, 0, 2); getchar(); return 0;

Algorithm Paradigm: Backtracking Time Complexity: O(n*n!)

If you are given two traversal sequences, can you construct the binary tree?
August 2, 2009

It depends on what traversals are given. If one of the traversal methods is Inorder then the tree can be constructed, otherwise not.

Therefore, following combination can uniquely identify a tree. Inorder and Preorder. Inorder and Postorder. Inorder and Level-order. And following do not. Postorder and Preorder. Preorder and Level-order. Postorder and Level-order. For example, Preorder, Level-order and Postorder traversals are same for the trees given in above diagram. Preorder Traversal = AB Postorder Traversal = BA Level-Order Traversal = AB So, even if three of them (Pre, Post and Level) are given, the tree can not be constructed.

Write an Efficient C Program to Reverse Bits of a Number


August 2, 2009

Method1 Simple Loop through all the bits of an integer. If a bit at ith position is set in the i/p no. then set the bit at (NO_OF_BITS 1) i in o/p. Where NO_OF_BITS is number of bits present in the given number.
/* Function to reverse bits of num */ unsigned int reverseBits(unsigned int num) { unsigned int NO_OF_BITS = sizeof(num) * 8; unsigned int reverse_num = 0, i, temp;

for (i = 0; i < NO_OF_BITS; i++) { temp = (num & (1 << i)); if(temp) reverse_num |= (1 << ((NO_OF_BITS - 1) - i)); }

return reverse_num; }

/* Driver function to test above function */ int main() { unsigned int x = 2; printf("%u", reverseBits(x)); getchar(); }

Above program can be optimized by removing the use of variable temp. See below the modified code.
unsigned int reverseBits(unsigned int num) { unsigned int NO_OF_BITS = sizeof(num) * 8; unsigned int reverse_num = 0; int i; for (i = 0; i < NO_OF_BITS; i++) { if((num & (1 << i))) reverse_num |= 1 << ((NO_OF_BITS - 1) - i); } return reverse_num; }

Time Complexity: O(log n) Space Complexity: O(1) Method 2 Standard The idea is to keep putting set bits of the num in reverse_num until num becomes zero. After num becomes zero, shift the remaining bits of reverse_num. Let num is stored using 8 bits and num be 00000110. After the loop you will get reverse_num as 00000011. Now you need to left shift reverse_num 5 more times and you get the exact reverse 01100000.
unsigned int reverseBits(unsigned int num) { unsigned int count = sizeof(num) * 8 - 1; unsigned int reverse_num = num;

num >>= 1;

while(num) { reverse_num <<= 1; reverse_num |= num & 1; num >>= 1; count--; } reverse_num <<= count; return reverse_num; }

int main() { unsigned int x = 1; printf("%u", reverseBits(x)); getchar(); }

Time Complexity: O(log n) Space Complexity: O(1) Method 3 Lookup Table: We can reverse the bits of a number in O(1) if we know the size of the number. We can implement it using look up table. Go through the below link for details. You will find some more interesting bit related stuff there. http://wwwgraphics.stanford.edu/~seander/bithacks.html#BitReverseTable

Write a function to reverse a linked list


August 2, 2009

Iterative Method Iterate trough the linked list. In loop, change next to prev, prev to

current and current to next.

Implementation of Iterative Method


#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to reverse the linked list */ static void reverse(struct node** head_ref) { struct node* prev = NULL;

struct node* current = *head_ref; struct node* next; while (current != NULL) { next = current->next;

current->next = prev; prev = current; current = next; } *head_ref = prev; }

/* Function to push a node */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Function to print linked list */ void printList(struct node *head) { struct node *temp = head; while(temp != NULL) { printf("%d ", temp->data);

temp = temp->next; } }

/* Drier program to test above function*/

int main() { /* Start with the empty list */ struct node* head = NULL;

push(&head, 20); push(&head, 4); push(&head, 15); push(&head, 85);

printList(head); reverse(&head); printf("\n Reversed Linked list \n"); printList(head); getchar(); }

Time Complexity: O(n) Space Complexity: O(1) Recursive Method:

1) Divide the list in two parts - first node and rest of the linked list. 2) Call reverse for the rest of the linked list. 3) Link rest to first. 4) Fix head pointer

void recursiveReverse(struct node** head_ref) { struct node* first; struct node* rest;

/* empty list */ if (*head_ref == NULL) return;

/* suppose first = {1, 2, 3}, rest = {2, 3} */ first = *head_ref; rest = first->next;

/* List has only one node */ if (rest == NULL)

return;

/* reverse the rest list and put the first element at the end */ recursiveReverse(&rest); first->next->next = first;

/* tricky step -- see the diagram */ first->next = NULL;

/* fix the head pointer */ *head_ref = rest; }

Time Complexity: O(n) Space Complexity: O(1) References: http://cslibrary.stanford.edu/105/LinkedListProblems.pdf

Write a C function to detect loop in a linked list


August 2, 2009

Below diagram shows a linked list with a loop

Following are different ways of doing this Use Hashing: Traverse the list one by one and keep putting the node addresses in a Hash Table. At any point, if NULL is reached then return false and if

next of current node points to any of the previously stored nodes in Hash then return true. Mark Visited Nodes: This solution requires modifications to basic linked list data structure. Have a visited flag with each node. Traverse the linked list and keep marking visited nodes. If you see a visited node again then there is a loop. This solution works in O(n) but requires additional information with each node. A variation of this solution that doesnt require modification to basic data structure can be implemented using hash. Just store the addresses of visited nodes in a hash and if you see an address that already exists in hash then there is a loop. Floyds Cycle-Finding Algorithm: This is the fastest method. Traverse linked list using two pointers. Move one pointer by one and other pointer by two. If these pointers meet at some node then there is a loop. If pointers do not meet then linked list doesnt have loop. Implementation of Floyds Cycle-Finding Algorithm:
#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

void push(struct node** head_ref, int new_data) { /* allocate node */

struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

int detectloop(struct node *list) { struct node *slow_p = list, *fast_p = list;

while(slow_p && fast_p && fast_p->next ) { slow_p = slow_p->next; fast_p = fast_p->next->next;

if (slow_p == fast_p) { printf("Found Loop"); return 1; } } return 0;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

push(&head, 20); push(&head, 4); push(&head, 15); push(&head, 10);

/* Create a loop for testing */ head->next->next->next->next = head; detectloop(head);

getchar(); }

Time Complexity: O(n) Auxiliary Space: O(1) References: http://en.wikipedia.org/wiki/Cycle_detection http://ostermiller.org/find_loop_singly_linked_list.html

Lucky Numbers
August 6, 2009

Lucky numbers are subset of integers. Rather than going into much theory, let us see the process of arriving at lucky numbers,

Take the set of integers 1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,19, First, delete every second number, we get following reduced set. 1,3,5,7,9,11,13,15,17,19, Now, delete every third number, we get 1, 3, 7, 9, 13, 15, 19,.. Continue this process indefinitely Any number that does NOT get deleted due to above process is called lucky. Therefore, set of lucky numbers is 1, 3, 7, 13, Now, given an integer n, write a function to say whether this number is lucky or not.

bool isLucky(int n)
Algorithm: Before every iteration, if we calculate position of the given no, then in a given iteration, we can determine if the no will be deleted. Suppose calculated position for the given no. is P before some iteration, and each Ith no. is going to be removed in this iteration, if P < I then input no is lucky, if P is such that P%I == 0 (I is a divisor of P), then input no is not lucky. Recursive Way:
#include <stdio.h> #define bool int

/* Returns 1 if n is a lucky no. ohterwise returns 0*/ bool isLucky(int n) { static int counter = 2;

/*variable next_position is just for readability of the program we can remove it and use n only */ int next_position = n; if(counter > n) return 1; if(n%counter == 0) return 0;

/*calculate next position of input no*/ next_position -= next_position/counter;

counter++; return isLucky(next_position); }

/*Driver function to test above function*/ int main() { int x = 5; if( isLucky(x) ) printf("%d is a lucky no.", x); else printf("%d is not a lucky no.", x); getchar(); }

Example: Lets us take an example of 19 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,15,17,18,19,20,21, 1,3,5,7,9,11,13,15,17,19,..

1,3,7,9,13,15,19,. 1,3,7,13,15,19, 1,3,7,13,19, In next step every 6th no .in sequence will be deleted. 19 will not be deleted after this step because position of 19 is 5th after this step. Therefore, 19 is lucky. Lets see how above C code finds out:
Current function call isLucky(19 ) isLucky(10) isLucky(7) isLucky(6) Position after this call 10 7 6 5 Counter for next call 3 4 5 6 Next Call isLucky(10) isLucky(7) isLucky(6) isLucky(5)

When isLucky(6) is called, it returns 1 (because counter > n). Iterative Way: Please see this comment for another simple and elegant implementation of the above algorithm. Please write comments if you find any bug in the given programs or other ways to solve the same problem.

Does C support function overloading?


August 6, 2009

First of all, what is function overloading? Function overloading is a feature of a programming language that allows one to have many functions with same name but with different signatures. This feature is present in most of the Object Oriented Languages such as C++ and Java. But C (not Object Oriented Language) doesnt support this feature. However, one can achieve the similar functionality in C indirectly. One of the approach is as follows. Have a void * type of pointer as an argument to the function. And another argument telling the actual data type of the first argument that is being passed.

int foo(void * arg1, int arg2);


Suppose, arg2 can be interpreted as follows. 0 = Struct1 type variable, 1 = Struct2 type variable etc. Here Struct1 and Struct2 are user defined struct types. While calling the function foo at different places

foo(arg1, 0); /*Here, arg1 is pointer to struct type Struct1 variable*/ foo(arg1, 1); /*Here, arg1 is pointer to struct type Struct2 variable*/
Since the second argument of the foo keeps track the data type of the first type, inside the function foo, one can get the actual data type of the first argument by typecast accordingly. i.e. inside the foo function
if(arg2 == 0) { struct1PtrVar = (Struct1 *)arg1; } else if(arg2 == 1) { struct2PtrVar = (Struct2 *)arg1; } else { /*Error Handling*/ }

There can be several other ways of implementing function overloading in C. But all of them will have to use pointers the most powerful feature of C. In fact, it is said that without using the pointers, one cant use C efficiently & effectively in a real world program!

How can I return multiple values from a function?


August 7, 2009

We all know that a function in C can return only one value. So how do we achieve the purpose of returning multiple values. Well, first take a look at the declaration of a function.
int foo(int arg1, int arg2);

So we can notice here that our interface to the function is through arguments and return value only. (Unless we talk about modifying the globals inside the function) Let us take a deeper lookEven though a function can return only one value but that value can be of pointer type. Thats correct, now youre speculating right! We can declare the function such that, it returns a structure type user defined variable or a pointer to it . And by the property of a structure, we know that a structure in C can hold multiple values of asymmetrical types (i.e. one int variable, four char variables, two float variables and so on) If we want the function to return multiple values of same data types, we could return the pointer to array of that data types. We can also make the function return multiple values by using the arguments of the function. How? By providing the pointers as arguments. Usually, when a function needs to return several values, we use one pointer in return instead of several pointers as argumentss.

Write a program to add two numbers in base 14


August 8, 2009

Asked by Anshya. Below are the different ways to add base 14 numbers.

Method 1 Thanks to Raj for suggesting this method.

1. Convert both i/p base 14 numbers to base 10. 2. Add numbers. 3. Convert the result back to base 14.
Method 2 Just add the numbers in base 14 in same way we add in base 10. Add numerals of both numbers one by one from right to left. If there is a carry while adding two numerals, consider the carry for adding next numerals. Let us consider the presentation of base 14 numbers same as hexadecimal numbers

A --> 10 B --> 11 C --> 12 D --> 13 Example: num1 = num2 =

1 C

2 D

A 3

1. Add A and 3, we get 13(D). Since 13 is smaller than 14, carry becomes 0 and resultant numeral becomes D 2. Add 2, D and carry(0). we get 15. Since 15 is greater than 13, carry becomes 1 and resultant numeral is 15 - 14 = 1 3. Add 1, C and carry(1). we get 14. Since 14 is greater

than 13, carry becomes 1 and resultant numeral is 14 - 14 = 0 Finally, there is a carry, so 1 is added as leftmost numeral and the result becomes 101D
Implementation of Method 2
# include <stdio.h> # include <stdlib.h> # define bool int

int getNumeralValue(char ); char getNumeral(int );

/* Function to add two numbers in base 14 */ char *sumBase14(char *num1, { int l1 = strlen(num1); int l2 = strlen(num2); char *res; int i; int nml1, nml2, res_nml; bool carry = 0; char *num2)

if(l1 != l2) { printf("Function doesn't support numbers of different" " lengths. If you want to add such numbers then" " prefix smaller number with required no. of zeroes"); getchar();

assert(0); }

/* Note the size of the allocated memory is one more than i/p lenghts for the cases where we have carry at the last like adding D1 and A1 */ res = (char *)malloc(sizeof(char)*(l1 + 1));

/* Add all numerals from right to left */ for(i = l1-1; i >= 0; i--) { /* Get decimal values of the numerals of i/p numbers*/ nml1 = getNumeralValue(num1[i]); nml2 = getNumeralValue(num2[i]);

/* Add decimal values of numerals and carry */ res_nml = carry + nml1 + nml2;

/* Check if we have carry for next addition of numerals */ if(res_nml >= 14) { carry = 1; res_nml -= 14; } else { carry = 0;

} res[i+1] = getNumeral(res_nml); }

/* if there is no carry after last iteration then result should not include 0th character of the resultant string */ if(carry == 0) return (res + 1);

/* if we have carry after last iteration then result should include 0th character */ res[0] = '1'; return res; }

/* Function to get value of a numeral For example it returns 10 for input 'A' 1 for '1', etc */ int getNumeralValue(char num) { if( num >= '0' && num <= '9') return (num - '0'); if( num >= 'A' && num <= 'D') return (num - 'A' + 10);

/* If we reach this line caller is giving invalid character so we assert and fail*/ assert(0);

/* Function to get numeral for a value. For example it returns 'A' for input 10 '1' for 1, etc */ char getNumeral(int val) { if( val >= 0 && val <= 9) return (val + '0'); if( val >= 10 && val <= 14) return (val + 'A' - 10);

/* If we reach this line caller is giving invalid no. so we assert and fail*/ assert(0); }

/*Driver program to test above functions*/ int main() { char *num1 = "DC2"; char *num2 = "0A3";

printf("Result is %s", sumBase14(num1, num2)); getchar(); return 0; }

Notes: Above approach can be used to add numbers in any base. We dont have to do string operations if base is smaller than 10. You can try extending the above program for numbers of different lengths.

Given a binary tree, print out all of its root-to-leaf paths one per line.
August 9, 2009

Asked by Varun Bhatia Here is the solution. Algorithm:

initialize: pathlen = 0, path[1000] /*1000 is some max limit for paths, it can change*/ /*printPathsRecur traverses nodes of tree in preorder */ printPathsRecur(tree, path[], pathlen) 1) If node is not NULL then a) push data to path array: path[pathlen] = node->data. b) increment pathlen pathlen++ 2) If node is a leaf node then print the path array. 3) Else a) Call printPathsRecur for left subtree printPathsRecur(node->left, path, pathLen) b) Call printPathsRecur for right subtree. printPathsRecur(node->right, path, pathLen)

Example:

Example Tree

Output for the above example will be

1 2 4 1 2 5 1 3
Implementation:
/*program to print all of its root-to-leaf paths for a tree*/ #include <stdio.h> #include <stdlib.h>

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; };

void printArray(int [], int); void printPathsRecur(struct node*, int [], int); struct node* newNode(int );

void printPaths(struct node*);

/* Given a binary tree, print out all of its root-to-leaf paths, one per line. Uses a recursive helper to do the work.*/ void printPaths(struct node* node) { int path[1000]; printPathsRecur(node, path, 0); }

/* Recursive helper function -- given a node, and an array containing the path from the root node up to but not including this node, print out all the root-leaf paths. */ void printPathsRecur(struct node* node, int path[], int pathLen) { if (node==NULL) return;

/* append this node to the path array */ path[pathLen] = node->data; pathLen++;

/* it's a leaf, so print the path that led to here */ if (node->left==NULL && node->right==NULL) { printArray(path, pathLen); } else { /* otherwise try both subtrees */

printPathsRecur(node->left, path, pathLen); printPathsRecur(node->right, path, pathLen); } }

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL;

return(node); }

/* Utility that prints out an array on a line */ void printArray(int ints[], int len) { int i; for (i=0; i<len; i++) { printf("%d ", ints[i]); } printf("\n"); }

/* Driver program to test mirror() */

int main() { struct node *root = newNode(1); root->left root->right root->left->left = newNode(2); = newNode(3); = newNode(4);

root->left->right = newNode(5);

/* Print all root-to-leaf paths of the input tree */ printPaths(root);

getchar(); return 0; }

References: http://cslibrary.stanford.edu/110/BinaryTrees.html

Lowest Common Ancestor in a Binary Search Tree.


August 9, 2009

Given the values of two nodes in a *binary search tree*, write a c program to find the lowest common ancestor. You may assume that both values already exist in the tree. The function prototype is as follows:

int FindLowestCommonAncestor(node* root, int value1, int value)

I/P : 4 and 14 O/P : 8 (Here the common ancestors of 4 and 14, are {8,20}. Of {8,20}, the lowest one is 8).
Here is the solution Algorithm: The main idea of the solution is While traversing Binary Search Tree from top to bottom, the first node n we encounter with value between n1 and n2, i.e., n1 < n < n2 is the Lowest or Least Common Ancestor(LCA) of n1 and n2 (where n1 < n2). So just traverse the BST in pre-order, if you find a node with value in between n1 and n2 then n is the LCA, if it's value is greater than both n1 and n2 then our LCA lies on left side of the node, if it's value is smaller than both n1 and n2 then LCA lies on right side. Implementation:
#include <stdio.h> #include <stdlib.h>

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node {

int data; struct node* left; struct node* right; };

struct node* newNode(int );

/* Function to find least comman ancestor of n1 and n2 */ int leastCommanAncestor(struct node* root, int n1, int n2) { /* If we have reached a leaf node then LCA doesn't exist If root->data is equal to any of the inputs then input is not valid. For example 20, 22 in the given figure */ if(root == NULL || root->data == n1 || root->data == n2) return -1;

/* If any of the input nodes is child of the current node we have reached the LCA. For example, in the above figure if we want to calculate LCA of 12 and 14, recursion should terminate when we reach 8*/ if((root->right != NULL) && (root->right->data == n1 || root->right->data == n2)) return root->data; if((root->left != NULL) && (root->left->data == n1 || root->left->data == n2)) return root->data;

if(root->data > n1 && root->data < n2) return root->data;

if(root->data > n1 && root->data > n2) return leastCommanAncestor(root->left, n1, n2); if(root->data < n1 && root->data < n2) return leastCommanAncestor(root->right, n1, n2); }

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data node->left = data; = NULL;

node->right = NULL;

return(node); }

/* Driver program to test mirror() */ int main() { struct node *root root->left root->right root->right->left = newNode(2); = newNode(1); = newNode(4); = newNode(3);

root->right->right = newNode(5);

/* Constructed binary search tree is

2 / \ 1 4 / \ 3 */ printf("\n The Least Common Ancestor is \n"); printf("%d", leastCommanAncestor(root, 3, 5)); 5

getchar(); return 0; }

Note that above function assumes that n1 is smaller than n2. Time complexity: Time complexity is O(Logn) for a balanced BST and O(n) for a skewed BST.

What is the purpose of a function prototype?


August 12, 2009

The Function prototype serves the following purposes 1) It tells the return type of the data that the function will return. 2) It tells the number of arguments passed to the function. 3) It tells the data types of the each of the passed arguments. 4) Also it tells the order in which the arguments are passed to the function. Therefore essentially, function prototype specifies the input/output interlace to the function i.e. what to give to the function and what to expect from the function. Prototype of a function is also called signature of the function. What if one doesnt specify the function prototype? Output of below kind of programs is generally asked at many places.

int main() { foo(); getchar(); return 0; } void foo() { printf("foo called"); }

If one doesnt specify the function prototype, the behavior is specific to C standard (either C90 or C99) that the compilers implement. Up to C90 standard, C compilers assumed the return type of the omitted function prototype as int. And this assumption at compiler side may lead to unspecified program behavior. Later C99 standard specified that compilers can no longer assume return type as int. Therefore, C99 became more restrict in type checking of function prototype. But to make C99 standard backward compatible, in practice, compilers throw the warning saying that the return type is assumed as int. But they go ahead with compilation. Thus, it becomes the responsibility of programmers to make sure that the assumed function prototype and the actual function type matches. To avoid all this implementation specifics of C standards, it is best to have function prototype.

Function to check if a singly linked list is palindrome


August 13, 2009

Asked by Varun Bhatia.

METHOD 1 (By reversing the list)

1. Get the middle of the linked list. 2. Reverse the second half of the linked list. 3. Compare the first half and second half. 4. Construct the original linked list by reversing the second half again and attaching it back to the first half
Implementation:
/* Program to check if a linked list is palindrome */ #include<stdio.h> #include<stdlib.h> #define bool int

/* Link list node */ struct node { char data; struct node* next; };

void reverse(struct node**); bool compareLists(struct node*, struct node *);

/* Function to check if given linked list is palindrome or not */ bool isPalindrome(struct node *head) { struct node *slow_ptr = head; struct node *fast_ptr = head; struct node *second_half; struct node *prev_of_slow_ptr = head; char res;

if(head!=NULL) { /* Get the middle of the list. Move slow_ptr by 1 and fast_ptrr by 2, slow_ptr will have the |_n/2_|th node */ while((fast_ptr->next)!=NULL && (fast_ptr->next->next)!=NULL) { fast_ptr = fast_ptr->next->next;

/*We need previous of the slow_ptr for linked lists with odd elements */

prev_of_slow_ptr = slow_ptr; slow_ptr = slow_ptr->next; }

/* Case where we have even no of elements */ if(fast_ptr->next != NULL) { second_half = slow_ptr->next; reverse(&second_half); slow_ptr->next = NULL; res = compareLists(head, second_half);

/*construct the original list back*/ reverse(&second_half); slow_ptr->next = second_half; }

/* Case where we have odd no. of elements. Neither first nor second list should have the middle element */ else { second_half = slow_ptr->next; prev_of_slow_ptr->next = NULL; reverse(&second_half); res = compareLists(head, second_half);

/*construct the original list back*/ reverse(&second_half); prev_of_slow_ptr->next = slow_ptr; slow_ptr->next = second_half; }

return res;

} }

/* Function to reverse the linked list function may change the head */ void reverse(struct node** head_ref) { struct node* prev = NULL;

Note that this

struct node* current = *head_ref; struct node* next; while (current != NULL) { next = current->next;

current->next = prev; prev = current; current = next; } *head_ref = prev; }

/* Function to check if two input lists have same data*/ int compareLists(struct node* head1, struct node *head2) { struct node* temp1 = head1; struct node* temp2 = head2;

while(temp1 && temp2) { if(temp1->data == temp2->data)

{ temp1 = temp1->next; temp2 = temp2->next; } else return 0; }

/* Both are empty reurn 1*/ if(temp1 == NULL && temp2 == NULL) return 1;

/* Will reach here when one is NULL and other is not */ return 0; }

/* Push a node to linked list. Note that this function changes the head */ void push(struct node** head_ref, char new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to pochar to the new node */ (*head_ref) } = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

push(&head, 'p'); push(&head, 'e'); push(&head, 'e'); push(&head, 'p');

/* p->e->e->p */ if(isPalindrome(head) == 1) printf("Linked list is Palindrome"); else printf("Linked list is not Palindrome");

getchar(); return 0; }

Time Complexity O(n) Auxiliary Space: O(1)

METHOD 2 (Using Recursion) Thanks to Sharad Chandra for suggesting this approach. Use two pointers left and right. Move right and left using recursion and check for following in each recursive call. 1) Sub-list is palindrome. 2) Value at current left and right are matching. If both above conditions are true then return true.
#define bool int #include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { char data; struct node* next; };

bool isPalindrome(struct node **left, struct node *right) { /* stop recursion here */ if (!right) return true;

/* If sub-list is not palindrome then no need to check for current left and right, return false */ bool isp = isPalindrome(left, right->next); if (isp == false) return false;

/* Check values at current left and right */ bool isp1 = (right->data == (*left)->data);

/* Move left to next node */ *left = (*left)->next; /* save next pointer */

return isp1; }

/* UTILITY FUNCTIONS */ /* Push a node to linked list. Note that this function changes the head */ void push(struct node** head_ref, char new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to pochar to the new node */ (*head_ref) } = new_node;

/* Drier program to test above function*/ int main() { /* Start with the empty list */ struct node* head = NULL;

push(&head, 'r'); push(&head, 'a'); push(&head, 'd'); push(&head, 'a'); push(&head, 'r');

/* r->a->d->a->r*/ if(isPalindrome(&head, head) == 1) printf("Linked list is Palindrome"); else printf("Linked list is not Palindrome");

getchar(); return 0; }

Time Complexity: O(n) Auxiliary Space: O(n) if Function Call Stack size is considered, otherwise O(1).

Search an element in a sorted and pivoted array


August 15, 2009

Question: An element in a sorted array can be found in O(log n) time via binary search. But suppose I rotate the sorted array at some pivot unknown

to you beforehand. So for instance, 1 2 3 4 5 might become 3 4 5 1 2. Devise a way to find an element in the rotated array in O(log n) time.

Solution: Thanks to Ajay Mishra for initial solution. Algorithm: Find the pivot point, divide the array in two sub-arrays and call binary search. The main idea for finding pivot is for a sorted (in increasing order) and pivoted array, pivot element is the only only element for which next element to it is smaller than it. Using above criteria and binary search methodology we can get pivot element in O(logn) time

Input arr[] = {3, 4, 5, 1, 2} Element to Search = 1 1) Find out pivot point and divide the array in two sub-arrays. (pivot = 2) /*Index of 5*/ 2) Now call binary search for one of the two sub-arrays. (a) If element is greater than 0th element then search in left array (b) Else Search in right array (1 will go in else as 1 < 0th element(3)) 3) If element is found in selected sub-array then return index Else return -1.
Implementation:

/* Program to search an element in a sorted and pivoted array*/ #include <stdio.h>

int findPivot(int[], int, int); int binarySearch(int[], int, int, int);

/* Searches an element no in a pivoted sorted array arrp[] of size arr_size */ int pivotedBinarySearch(int arr[], int arr_size, int no) { int pivot = findPivot(arr, 0, arr_size-1);

// If we didn't find a pivot, then array is not rotated at all if (pivot == -1) return binarySearch(arr, 0, arr_size-1, no);

// If we found a pivot, then first compare with pivot and then // search in two subarrays around pivot if (arr[pivot] == no) return pivot; if (arr[0] <= no) return binarySearch(arr, 0, pivot-1, no); else return binarySearch(arr, pivot+1, arr_size-1, no); }

/* Function to get pivot. For array 3, 4, 5, 6, 1, 2 it will return 3 */ int findPivot(int arr[], int low, int high)

{ if (high < low) return -1;

int mid = (low + high)/2;

/*low + (high - low)/2;*/

if (mid < high && arr[mid] > arr[mid + 1]) return mid; if (arr[low] >= arr[mid]) return findPivot(arr, low, mid-1); else return findPivot(arr, mid + 1, high); }

/* Standard Binary Search function*/ int binarySearch(int arr[], int low, int high, int no) { if (high < low) return -1;

int mid = (low + high)/2;

/*low + (high - low)/2;*/

if (no == arr[mid]) return mid; if (no > arr[mid]) return binarySearch(arr, (mid + 1), high, no); else return binarySearch(arr, low, (mid -1), no); }

/* Driver program to check above functions */ int main() { int arr[] = {3, 4, 5, 1, 2}; int arr_size = sizeof(arr)/sizeof(arr[0]); int no = 3; printf("Index of the element is %d", pivotedBinarySearch(arr, arr_size, no)); return 0; }

Output:

Index of the element is 0


Please note that the solution may not work for cases where the input array has duplicates. Time Complexity O(logn)

The Great Tree-List Recursion Problem.


August 15, 2009

Asked by Varun Bhatia. Question: Write a recursive function treeToList(Node root) that takes an ordered binary tree and rearranges the internal pointers to make a circular doubly linked list out of the tree nodes. Theprevious pointers should be stored in the small field and the next pointers should be stored in the large field. The list should be arranged so that the nodes are in increasing order. Return the head pointer to the new list. This is very well explained and implemented at http://cslibrary.stanford.edu/109/TreeListRecursion.html

Count set bits in an integer


August 19, 2009

Write an efficient program to count number of 1s in binary representation of an integer. 1. Simple Method Loop through all bits in an integer, check if a bit is set and if it is then increment the set bit count. See below program.
/* Function to get no of set bits in binary representation of passed binary no. */ int countSetBits(unsigned int n) { unsigned int count = 0; while(n) { count += n & 1; n >>= 1; } return count; }

/* Program to test function countSetBits */ int main() { int i = 9; printf("%d", countSetBits(i)); getchar(); return 0; }

Time Complexity: (-)(logn) (Theta of logn) 2. Brian Kernighans Algorithm: Subtraction of 1 from a number toggles all the bits (from right to left) till the rightmost set bit(including the righmost set bit). So if we

subtract a number by 1 and do bitwise & with itself (n & (n-1)), we unset the righmost set bit. If we do n & (n-1) in a loop and count the no of times loop executes we get the set bit count. Beauty of the this solution is number of times it loops is equal to the number of set bits in a given integer.

Initialize count: = 0 If integer n is not zero (a) Do bitwise & with (n-1) and assign the value back to n n: = n&(n-1) (b) Increment count by 1 (c) go to step 2 3 Else return count
Implementation of Brian Kernighans Algorithm:
#include<stdio.h>

1 2

/* Function to get no of set bits in binary representation of passed binary no. */ int countSetBits(int n) { unsigned int count = 0; while (n) { n &= (n-1) ; count++; } return count; }

/* Program to test function countSetBits */ int main() { int i = 9; printf("%d", countSetBits(i)); getchar(); return 0; }

Example for Brian Kernighans Algorithm:

n = 9 (1001) count = 0 Since 9 > 0, subtract by 1 and do bitwise & with (9-1) n = 9&8 (1001 & 1000) n = 8 count = 1 Since 8 > 0, subtract by 1 and do bitwise & with (8-1) n = 8&7 (1000 & 0111) n = 0 count = 2 Since n = 0, return count which is 2 now.
Time Complexity: O(logn) 3. Using Lookup table: We can count bits in O(1) time using lookup table. Please seehttp://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet Table for details. You can find one use of counting set bits at http://geeksforgeeks.org/?p=1465

References: http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaiv e

Write a C macro PRINT(x) which prints x


August 23, 2009

At the first look, it seems that writing a C macro which prints its argument is childs play. Following program should work i.e. it should print x
#define PRINT(x) (x) int main() { printf("%s",PRINT(x)); return 0; }

But it would issue compile error because the data type of x, which is taken as variable by the compiler, is unknown. Now it doesnt look so obvious. Isnt it? Guess what, the followings also wont work
#define PRINT(x) ('x') #define PRINT(x) ("x")

But if we know one of lesser known traits of C language, writing such a macro is really a childs play. In C, theres a # directive, also called Stringizing Operator, which does this magic. Basically # directive converts its argument in a string. Voila! it is so simple to do the rest. So the above program can be modified as below.
#define PRINT(x) (#x) int main() { printf("%s",PRINT(x)); return 0;

Now if the input is PRINT(x), it would print x. In fact, if the input is PRINT(geeks), it would print geeks. You may find the details of this directive from Microsoft portal here.

Copy a linked list with next and arbit pointer


August 24, 2009

You are given a Double Link List with one pointer of each node pointing to the next node just like in a single link list. The second pointer however CAN point to any node in the list and not just the previous node. Now write a program in O(n) time to duplicate this list. That is, write a program which will create a copy of this list. Let us call the second pointer as arbit pointer as it can point to any arbitrary node in the linked list.

Arbitrary pointers are shown in red and next pointers in black Figure 1 Method 1 (Uses O(n) extra space) This method stores the next and arbitrary mappings (of original list) in an array first, then modifies the original Linked List (to create copy), creates a copy. And finally restores the original list. 1) Create all nodes in copy linked list using next pointers. 3) Store the node and its next pointer mappings of original linked list. 3) Change next pointer of all nodes in original linked list to point to the corresponding node in copy linked list. Following diagram shows status of both Linked Lists after above 3

steps. The red arrow shows arbit pointers and black arrow shows next pointers.

Figure 2 4) Change the arbit pointer of all nodes in copy linked list to point to corresponding node in original linked list. 5) Now construct the arbit pointer in copy linked list as below and restore the next pointer of nodes in the original linked list.

copy_list_node->arbit = copy_list_node->arbit>arbit->next; copy_list_node = copy_list_node->next;


6) Restore the next pointers in original linked list from the stored mappings(in step 2). Time Complexity: O(n) Auxiliary Space: O(n)

Method 2 (Uses Constant Extra Space) Thanks to Saravanan Mani for providing this solution. This solution works using constant space. 1) Create the copy of node 1 and insert it between node 1 & node 2 in original Linked List, create the copy of 2 and insert it between 2 & 3.. Continue in this fashion, add the copy of N afte the Nth node 2) Now copy the arbitrary link in this fashion

original->next->arbitrary = original>arbitrary->next; /*TRAVERSE TWO NODES*/


This works because original->next is nothing but copy of original and Original->arbitrary->next is nothing but copy of arbitrary. 3) Now restore the original and copy linked lists in this fashion in a single loop.

original->next = original->next->next; copy->next = copy->next->next;


4) Make sure that last element of original->next is NULL. Time Complexity: O(n) Auxiliary Space: O(1) Asked by Varun Bhatia. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Memory efficient doubly linked list


August 24, 2009

Asked by Varun Bhatia. Question: Write a code for implementation of doubly linked list with use of single pointer in each node. Solution: This question is solved and very well explained at http://www.linuxjournal.com/article/6828. We also recommend to read http://en.wikipedia.org/wiki/XOR_linked_list

How to print % using printf()?


August 30, 2009

Asked by Tanuj

Here is the standard prototype of printf function in C.

int printf(const char *format, ...);


The format string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications, each of argument (and it is an error if insufficiently many arguments are given). The character % is followed by one of the following characters. The flag character The field width The precision The length modifier The conversion specifier: See http://swoolley.org/man.cgi/3/printf for details of all the above characters. The main thing to note in the standard is the below line about conversion specifier.

A `%' is written. No argument is converted. The complete conversion specification is`%%'.


So we can print % using %%
/* Program to print %*/ #include<stdio.h> /* Program to print %*/ int main() { printf("%%"); getchar(); return 0; }

We can also print % using below.

printf("%c", '%'); printf("%s", "%");

How to declare a pointer to a function?


September 1, 2009

Well, we assume that you know what does it mean by pointer in C. So how do we create a pointer to an integer in C? Huh..it is pretty simple..

int * ptrInteger; /*We have put a * operator between int and ptrInteger to create a pointer.*/
Here ptrInteger is a pointer to integer. If you understand this, then logically we should not have any problem in declaring a pointer to a function So let us first see ..how do we declare a function? For example,

int foo(int);
Here foo is a function that returns int and takes one argument of int type. So as a logical guy will think, by putting a * operator between int and foo(int) should create a pointer to a function i.e.

int * foo(int);
But Oops..C operator precedence also plays role here ..so in this case, operator () will take priority over operator *. And the above declaration will mean a function foo with one argument of int type and return value of int * i.e. integer pointer. So it did something that we didnt want to do. So as a next logical step, we have to bind operator * with foo somehow. And for this, we would change the default precedence of C operators using () operator.

int (*foo)(int);

Thats it. Here * operator is with foo which is a function name. And it did the same that we wanted to do. So that wasnt as difficult as we thought earlier!

Find the node with minimum value in a Binary Search Tree


September 3, 2009

This is quite simple. Just traverse the node from root to left recursively until left is NULL. The node whose left is NULL is the node with minimum value.

For the above tree, we start with 20, then we move left 8, we keep on moving to left until we see NULL. Since left of 4 is NULL, 4 is the node with minimum value.
#include <stdio.h> #include<stdlib.h>

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right;

};

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data node->left = data; = NULL;

node->right = NULL;

return(node); }

/* Give a binary search tree and a number, inserts a new node with the given number in the correct place in the tree. Returns the new root pointer which the caller should then use (the standard trick to avoid using reference parameters). */ struct node* insert(struct node* node, int data) { /* 1. If the tree is empty, return a new, single node */ if (node == NULL) return(newNode(data)); else

{ /* 2. Otherwise, recur down the tree */ if (data <= node->data) node->left else node->right = insert(node->right, data); = insert(node->left, data);

/* return the (unchanged) node pointer */ return node; } }

/* Given a non-empty binary search tree, return the minimum data value found in that tree. Note that the entire tree does not need to be searched. */ int minValue(struct node* node) { struct node* current = node;

/* loop down to find the leftmost leaf */ while (current->left != NULL) { current = current->left; } return(current->data); }

/* Driver program to test sameTree function*/ int main() {

struct node* root = NULL; root = insert(root, 4); insert(root, 2); insert(root, 1); insert(root, 3); insert(root, 6); insert(root, 5);

printf("\n Minimum value in BST is %d", minValue(root)); getchar(); return 0; }

Time Complexity: O(n) Worst case happens for left skewed trees. Similarly we can get the maximum value by recursively traversing the right node of a binary search tree. References: http://cslibrary.stanford.edu/110/BinaryTrees.html

Merge an array of size n into another array of size m+n


September 5, 2009

Asked by Binod Question: There are two sorted arrays. First one is of size m+n containing only m elements. Another one is of size n and contains n elements. Merge these two arrays into the first array of size m+n such that the output is sorted. Input: array with m+n elements (mPlusN[]).

NA => Value is not filled/available in array mPlusN[]. There should be n such array blocks. Input: array with n elements (N[]).

Output: N[] merged into mPlusN[] (Modified mPlusN[])

Algorithm:

Let first array be mPlusN[] and other array be N[] 1) Move m elements of mPlusN[] to end. 2) Start from nth element of mPlusN[] and 0th element of N[] and merge them into mPlusN[].
Implementation:
/* Assuming -1 is filled for the places where element is not available */ #define NA -1

/* Function to move m elements at the end of array mPlusN[] */ void moveToEnd(int mPlusN[], int size) { int i = 0, j = size - 1; for (i = size-1; i >= 0; i--) if(mPlusN[i] != NA)

{ mPlusN[j] = mPlusN[i]; j--; } }

/* Merges array N[] of size n into array mPlusN[] of size m+n*/ int merge(int mPlusN[], int N[], int m, int n) { int i = n; /* Current index of i/p part of mPlusN[]*/

int j = 0; /* Current index of N[]*/ int k = 0; /* Current index of of output mPlusN[]*/ while(k <= (m+n)) { /* Take the element from mPlusN[] if a) its value is smaller and we have not reached end of it b) We have reached end of N[] */ if((i < (m+n) && mPlusN[i] <= N[j]) || ( j == n)) { mPlusN[k] = mPlusN[i]; k++; i++; } else { mPlusN[k] = N[j]; k++; j++;

} } }

/* Utility that prints out an array on a line */ void printArray(int arr[], int size) { int i; for (i=0; i < size; i++) printf("%d ", arr[i]);

printf("\n"); }

/* Driver function to test above functions */ int main() { /* Initialize arrays */ int mPlusN[9] = {2, 8, NA, NA, NA, 13, NA, 15, 20}; int N[] = {5, 7, 9, 25}; int m = 5, n = 4;

/*Move the m elements at the end of mPlusN*/ moveToEnd(mPlusN, 9);

/*Merge N[] into mPlusN[] */ merge(mPlusN, N, 5, 4);

/* Print the resultant mPlusN */

printArray(mPlusN, 9); getchar(); }

Time Complexity: O(m+n) Please write comment if you find any bug in the above program or a better way to solve the same problem.

Count number of bits to be flipped to convert A to B


September 5, 2009

Suggested by Dheeraj Question: You are given two numbers A and B. Write a program to count number of bits needed to be flipped to convert A to B. Solution:

1. Calculate XOR of A and B. a_xor_b = A ^ B 2. Count the set bits in the above calculated XOR result. countSetBits(a_xor_b)
XOR of two number will have set bits only at those places where A differs from B. Example:

A = 1001001 B = 0010101 a_xor_b = 1011100 No of bits need to flipped = set bit count in a_xor_b i.e. 4
To get the set bit count please see another post on this portal http://geeksforgeeks.org/?p=1176

Operating Systems | Set 1

September 6, 2009

Following questions have been asked in GATE CS exam. 1. Which of the following is NOT a valid deadlock prevention scheme? (GATE CS 2000) (a) Release all resources before requesting a new resource (b) Number the resources uniquely and never request a lower numbered resource than the last one requested. (c) Never request a resource after releasing any resource (d) Request and all required resources be allocated before execution. Answer: (c) References: http://www.cs.jhu.edu/~yairamir/cs418/os4/sld013.htm http://en.wikipedia.org/wiki/Deadlock 2. Let m[0]m[4] be mutexes (binary semaphores) and P[0] . P[4] be processes. Suppose each process P[i] executes the following:

wait (m[i]); wait(m[(i+1) mode 4]); -----release (m[i]); release (m[(i+1)mod 4]);
This could cause (GATE CS 2000) (a) Thrashing (b) Deadlock (c) Starvation, but not deadlock (d) None of the above Answer: (b) Explanation: You can easily see a deadlock in a situation where.. P[0] has acquired m[0] and waiting for m[1] P[1] has acquired m[1] and waiting for m[2]

P[2] has acquired m[2] and waiting for m[3] P[3] has acquired m[3] and waiting for m[0]

3. A graphics card has on board memory of 1 MB. Which of the following modes can the card not support? (GATE CS 2000) (a) 1600 x 400 resolution with 256 colours on a 17 inch monitor (b) 1600 x 400 resolution with 16 million colours on a 14 inch monitor (c) 800 x 400 resolution with 16 million colours on a 17 inch monitor (d) 800 x 800 resolution with 256 colours on a 14 inch monitor Answer: (b) Explanation: Monitor size doesnt matter here. So, we can easily deduct that answer should be (b) as this has the highest memory requirements. Let us verify it. Number of bits required to store a 16M colors pixel = ceil(log2(16*1000000)) = 24 Number of bytes required for 1600 x 400 resolution with 16M colors = (1600 * 400 * 24)/8 which is 192000000 (greater than 1MB).

4 Consider a virtual memory system with FIFO page replacement policy. For an arbitrary page access pattern, increasing the number of page frames in main memory will (GATE CS 2001) a) Always decrease the number of page faults b) Always increase the number of page faults c) Some times increase the number of page faults d) Never affect the number of page faults Answer: (c) Explanation: Incrementing the number of page frames doesnt always decrease the page faults (Beladys Anomaly). For details see http://en.wikipedia.org/wiki/Belady%27s_anomaly

5. Which of the following requires a device driver? (GATE CS

2001) a) Register b) Cache c) Main memory d) Disk Answer: (d)

Divide a string in N equal parts


September 9, 2009

Difficulty Level: Rookie Question: Write a program to print N equal parts of a given string. Solution: 1) Get the size of the string using string function strlen() (present in string.h) 2) Get size of a part.

part_size = string_length/n
3) Loop through the input string. In loop, if index becomes multiple of part_size then put a part separator(\n) Implementation:
#include<stdio.h> #include<string.h>

/* Function to print n equal parts of str*/ void divideString(char *str, int n) { int str_size = strlen(str); int i; int part_size;

/*Check if string can be divided in n equal parts */ if(str_size%n != 0) { printf("Invalid Input: String size is not divisible by n"); return; }

/* Calculate the size of parts to find the division points*/ part_size = str_size/n; for(i = 0; i< str_size; i++) { if(i%part_size == 0) printf("\n"); /* newline separator for different parts */ printf("%c", str[i]); } }

int main() { /*length od string is 28*/ char *str = "a_simple_divide_string_quest";

/*Print 4 equal parts of the string */ divideString(str, 4);

getchar(); return 0; }

In above solution, we are simply printing the N equal parts of the string. If we want individual parts to be stored then we need to allocate part_size + 1 memory for all N parts (1 extra for string termination character \0), and store the addresses of the parts in an array of character pointers.

Automata Theory | Set 1


September 12, 2009

Following questions have been asked in GATE CS exam. 1. Let S and T be language over ={a,b} represented by the regular expressions (a+b*)* and (a+b)*, respectively. Which of the following is true? (GATE CS 2000) (a) ScT (S is a subset of T) (b) TcS (T is a subset of S) (c) S=T (d) SnT= Answer: (c). 2. Let L denotes the language generated by the grammar S OSO/00. Which of the following is true? (GATE CS 2000) (a) L = O (b) L is regular but not O (c) L is context free but not regular (d) L is not context free Answer: (b) Explanation: Please note that grammar itself is not regular but language L is regular as L can be represented using a regular grammar, for example S -> S00/00. References: http://en.wikipedia.org/wiki/Regular_grammar

3. Consider the following two statements: S1: { 0^2n |n >= l} is a regu1ar language

S2: { 0^m 0^n 0^(m+n) l m >= 1 and n >= 2} is a regu1ar language Which of the following statements is correct? (GATE CS 2001) a) Only S1 is correct b) Only S2 is correct c) Both S1 and S2 are correct d) None of S1 and S2 is correct Answer: (c) Explanation: S1 can be written as (00)^n where n >= 1. And S2 can be written as (00)^(m+n) where m >=2 and n >= 1. S2 can be further reduced to (00)^x where x >= 3. We can easily write regular grammars for both S1 and S2. G1 -> G100/00 (For S1) G2 -> G200/000000 (For S2)

4. Which of the following statements in true? (GATE CS 2001) (a) If a language is context free it can always be accepted by a deterministic push-down automaton (b) The union of two context free languages is context free (c) The intersection of two context free languages is context free (d) The complement of a context free language is context free Answer: (b) Explanation: Context-free languages are closed under the following operations. That is, if L and P are context-free languages and D is a regular language, the following languages are context-free as well: the Kleene star L * of L the image (L) of L under a homomorphism the concatenation of L and P the union of L and P the intersection of L with a regular language D (L n D). Context-free languages are not closed under complement, intersection, or difference. Why a) is not true? The language recognized by deterministic pushdown automaton is deterministic context free language. Not all context-free languages are

deterministic. This is unlike the situation for deterministic finite automata, which are also a subset of the nondeterministic finite automata but can recognize the same class of languages (as demonstrated by the subset construction). References: http://en.wikipedia.org/wiki/Context-free_language http://en.wikipedia.org/wiki/Deterministic_pushdown_automaton

5. Given an arbitrary non-deterministic finite automaton (NFA) with N states, the maximum number of states in an equivalent minimized DFA is at least. (GATE CS 2001) (a) N^2 (b) 2^N (c) 2N (d) N! Answer: (b) References: http://en.wikipedia.org/wiki/Powerset_construction

Output of C Programs | Set 7


September 13, 2009

Predict the output of below programs Question 1


int main() { int i = 0; while (i <= 4) { printf("%d", i); if (i > 3) goto inside_foo; i++;

} getchar(); return 0; }

void foo() { inside_foo: printf("PP"); }

Output: Compiler error: Label inside_foo used but not defined. Explanation: Scope of a label is within a function. We cannot goto a label from other function. Question 2
#define a 10 int main() { #define a 50 printf("%d",a);

getchar(); return 0; }

Output: 50 Preprocessor doesnt give any error if we redefine a preprocessor directive. It may give warning though. Preprocessor takes the most recent value before use of and put it in place of a.

Now try following


#define a 10 int main() { printf("%d ",a); #define a 50 printf("%d ",a);

getchar(); return 0; }

Question 3
int main() { char str[] = "geeksforgeeks"; char *s1 = str, *s2 = str; int i;

for(i = 0; i < 7; i++) { printf(" %c ", *str); ++s1; }

for(i = 0; i < 6; i++) { printf(" %c ", *s2);

++s2; }

getchar(); return 0; }

Output ggggggggeeksf Explanation Both s1 and s2 are initialized to str. In first loop str is being printed and s1 is being incremented, so first loop will print only g. In second loop s2 is incremented and s2 is printed so second loop will print g e eksf Question 4
int main() { char str[] = "geeksforgeeks"; int i; for(i=0; str[i]; i++) printf("\n%c%c%c%c", str[i], *(str+i), *(i+str), i[str]);

getchar(); return 0; }

Output: gggg eeee eeee kkkk ssss

ffff oooo rrrr gggg eeee eeee kkkk ssss Explanaition: Following are different ways of indexing both array and string. arr[i] *(arr + i) *(i + arr) i[arr] So all of them print same character. Question 5
int main() { char *p; printf("%d %d ", sizeof(*p), sizeof(p));

getchar(); return 0; }

Output: Compiler dependent. I got output as 1 4 Explanation: Output of the above program depends on compiler. sizeof(*p) gives size of character. If characters are stored as 1 byte then sizeof(*p) gives 1.

sizeof(p) gives the size of pointer variable. If pointer variables are stored as 4 bytes then it gives 4.

Given a string, find its first non-repeating character


September 16, 2009

Algorithm:

1) Scan the string from left to right and construct the count array. 2) Again, scan the string from left to right and check for count of each character, if you find an element who's count is 1, return it.
Example:

Input string: str = geeksforgeeks 1: Construct character count array from the input string. .... count['e'] = 4 count['f'] = 1 count['g'] = 2 count['k'] = 2 2: Get the first character who's count is 1 ('f').
Implementation:
#include<stdlib.h> #include<stdio.h> #define NO_OF_CHARS 256

/* Returns an array of size 256 containg count of characters in the passed char array */

int *getCharCountArray(char *str) { int *count = (int *)calloc(sizeof(int), NO_OF_CHARS); int i; for (i = 0; *(str+i); count[*(str+i)]++; return count; } i++)

/* The function returns index of first non-repeating character in a string. If all characters are repeating then reurns -1 */ int firstNonRepeating(char *str) { int *count = getCharCountArray(str); int index = -1, i;

for (i = 0; *(str+i); {

i++)

if(count[*(str+i)] == 1) { index = i; break; } } return index; }

/* Driver program to test above function */

int main() { char str[] = "geeksforgeeks"; int index = firstNonRepeating(str);

if(index == -1) printf("Either all characters are repeating or string is empty"); else printf("First non-repeating character is %c", str[index]); getchar(); return 0; }

Time Complexity: O(n)

Given a linked list which is sorted, how will you insert in sorted way
September 17, 2009

Algorithm: Let input linked list is sorted in increasing order.

1) If Linked list is empty then make the node as head and return it. 2) If value of the node to be inserted is smaller than value of head node then insert the node at start and make it head. 3) In a loop, find the appropriate node after which the input node (let 9) is to be inserted. To find the appropriate node start from head, keep moving until you reach a node GN (10 in the below diagram) who's value is greater than the input node. The node just before GN is the appropriate node (7).

4) Insert the node (9) after the appropriate node (7) found in step 3.
Initial Linked List

Linked List after insertion of 9

Implementation:
/* Program to insert in a sorted list */ #include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* function to insert a new_node in a list. Note that this function expects a pointer to head_ref as this can modify the head of the input linked list (similar to push())*/ void sortedInsert(struct node** head_ref, struct node* new_node) { struct node* current; /* Special case for the head end */ if (*head_ref == NULL || (*head_ref)->data >= new_node->data)

{ new_node->next = *head_ref; *head_ref = new_node; } else { /* Locate the node before the point of insertion */ current = *head_ref; while (current->next!=NULL && current->next->data < new_node->data) { current = current->next; } new_node->next = current->next; current->next = new_node; } }

/* BELOW FUNCTIONS ARE JUST UTILITY TO TEST sortedInsert */

/* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(struct node** head_ref, int new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data

*/

new_node->data

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to point to the new node */ (*head_ref) } = new_node;

/* Function to print linked list */ void printList(struct node *head) { struct node *temp = head; while(temp != NULL) { printf("%d ", temp->data);

temp = temp->next; } }

/* Drier program to test count function*/ int main() { /* Start with the empty list */ struct node* head = NULL; int value_to_insert;

/* Use push() to construct below list 2->5->7->10->15 */

push(&head, 15); push(&head, 10); push(&head, 7); push(&head, 5); push(&head, 2);

/* Let us try inserting 9 */ value_to_insert = 9; struct node* new_node = (struct node*) malloc(sizeof(struct node)); new_node->data = value_to_insert;

printf("\n List before insertion of %d \n", value_to_insert); printList(head);

sortedInsert(&head, new_node);

printf("\n List after insertion of %d \n", value_to_insert); printList(head);

getchar(); return 1; }

Shorter Implementation using double pointers Thanks to Murat M Ozturk for providing this solution. Please see Murat M Ozturks comment below for complete function. The code uses double pointer to keep track of the next pointer of the previous node (after which new node is being inserted). Note that below line in code changes current to have address of next pointer in a node.

current = &((*current)->next);

Also, note below comments.

new_node->next = *current; /* Copies the value-at-address current to new_node's next poi

*current = new_node; being inserted */

/* Fix next pointer of the node (using it's address) after which n

Time Complexity: O(n) References: http://cslibrary.stanford.edu/105/LinkedListProblems.pdf

Operating Systems | Set 2


September 18, 2009

Following questions have been asked in GATE CS exam. 1. Consider a machine with 64 MB physical memory and a 32-bit virtual address space. If the page size is 4KB, what is the approximate size of the page table? (GATE 2001) (a) 16 MB (b) 8 MB (c) 2 MB (d) 24 MB Answer: (c) Explanation: A page entry is used to get address of physical memory. Here we assume that single level of Paging is happening. So the resulting page table will contain entries for all the pages of the Virtual address space.

Number of entries in page table = (virtual address space size)/(page size)

Using above formula we can say that there will be 2^(32-12) = 2^20 entries in page table. No. of bits required to address the 64MB Physical memory = 26. So there will be 2^(26-12) = 2^14 page frames in the physical memory. And page table needs to store the address of all these 2^14 page frames. Therefore, each page table entry will contain 14 bits address of the page frame and 1 bit for valid-invalid bit. Since memory is byte addressable. So we take that each page table entry is 16 bits i.e. 2 bytes long.

Size of page table = (total number of page table entries) *(size of a page table entry) = (2^20 *2) = 2MB
For the clarity of the concept, please see the following figure. As per our question, here p = 20, d = 12 and f = 14.

2. Consider Petersons algorithm for mutual exclusion between two concurrent processes i and j. The program executed by process is shown below.

repeat

flag [i] = true; turn = j; while ( P ) do no-op; Enter critical section, perform actions, then exit critical section flag [ i ] = false; Perform other non-critical section actions. until false;
For the program to guarantee mutual exclusion, the predicate P in the while loop should be (GATE 2001) a) flag [j] = true and turn = i b) flag [j] = true and turn = j c) flag [i] = true and turn = j d) flag [i] = true and turn = i Answer: (b) Basically, Petersons algorithm provides guaranteed mutual exclusion by using the two following constructs flag[] and turn. flag[] controls that the willingness of a process to be entered in critical section. While turn controls the process that is allowed to be entered in critical section. So by replacing P with the following, flag [j] = true and turn = j process i will not enter critical section if process j wants to enter critical section and it is process jsturn to enter critical section. The same concept can be extended for more than two processes. For details, refer the following. References: http://en.wikipedia.org/wiki/Peterson%27s_algorithm

3 More than one word are put in one cache block to (GATE 2001) (a) exploit the temporal locality of reference in a program (b) exploit the spatial locality of reference in a program

(c) reduce the miss penalty (d) none of the above Answer: (b) Temporal locality refers to the reuse of specific data and/or resources within relatively small time durations. Spatial locality refers to the use of data elements within relatively close storage locations. To exploit the spatial locality, more than one word are put into cache block. References: http://en.wikipedia.org/wiki/Locality_of_reference

4. Which of the following statements is false? (GATE 2001) a) Virtual memory implements the translation of a programs address space into physical memory address space b) Virtual memory allows each program to exceed the size of the primary memory c) Virtual memory increases the degree of multiprogramming d) Virtual memory reduces the context switching overhead Answer: (d) In a system with virtual memory context switch includes extra overhead in switching of address spaces. References: http://www.itee.adfa.edu.au/~spike/CSA2/Lectures00/lecture.vm.htm 5. Consider a set of n tasks with known runtimes r1, r2, rn to be run on a uniprocessor machine. Which of the following processor scheduling algorithms will result in the maximum throughput? (GATE 2001) (a) Round-Robin (b) Shortest-Job-First (c) Highest-Response-Ratio-Next (d) First-Come-First-Served Answer: (b)

Operating Systems | Set 3

September 21, 2009

Following questions have been asked in GATE CS exam. 1. Suppose the time to service a page fault is on the average 10 milliseconds, while a memory access takes 1 microsecond. Then a 99.99% hit ratio results in average memory access time of (GATE CS 2000) (a) 1.9999 milliseconds (b) 1 millisecond (c) 9.999 microseconds (d) 1.9999 microseconds Answer: (d) Explanation:

Average memory access time = [(% of page miss)*(time to service a page fault) + (% of page hit)*(memory access time)]/100
So, average memory access time in microseconds is. (99.99*1 + 0.01*10*1000)/100 = (99.99+100)/1000 = 199.99/1000 =1.9999 s

2. Which of the following need not necessarily be saved on a context switch between processes? (GATE CS 2000) (a) General purpose registers (b) Translation look-aside buffer (c) Program counter (d) All of the above Answer: (b) Explanation: In a process context switch, the state of the first process must be saved somehow, so that, when the scheduler gets back to the execution of the first process, it can restore this state and continue.

The state of the process includes all the registers that the process may be using, especially the program counter, plus any other operating system specific data that may be necessary. A Translation lookaside buffer (TLB) is a CPU cache that memory management hardware uses to improve virtual address translation speed. A TLB has a fixed number of slots that contain page table entries, which map virtual addresses to physical addresses. On a context switch, some TLB entries can become invalid, since the virtual-to-physical mapping is different. The simplest strategy to deal with this is to completely flush the TLB. References: http://en.wikipedia.org/wiki/Context_switch http://en.wikipedia.org/wiki/Translation_lookaside_buffer#Context_swit ch

3. Where does the swap space reside ? (GATE 2001) (a) RAM (b) Disk (c) ROM (d) On-chip cache Answer: (b) Explanation: Swap space is an area on disk that temporarily holds a process memory image. When physical memory demand is sufficiently low, process memory images are brought back into physical memory from the swap area. Having sufficient swap space enables the system to keep some physical memory free at all times. References: http://docs.hp.com/en/B2355-90672/ch06s02.html

4. Which of the following does not interrupt a running process? (GATE CS 2001) (a) A device (b) Timer (c) Scheduler process (d) Power failure

Answer: (c) Explanation: Scheduler process doesnt interrupt any process, its Job is to select the processes for following three purposes. Long-term scheduler(or job scheduler) selects which processes should be brought into the ready queue Short-term scheduler(or CPU scheduler) selects which process should be executed next and allocates CPU. Mid-term Scheduler (Swapper)- present in all systems with virtual memory, temporarily removes processes from main memory and places them on secondary memory (such as a disk drive) or vice versa. The mid-term scheduler may decide to swap out a process which has not been active for some time, or a process which has a low priority, or a process which is page faulting frequently, or a process which is taking up a large amount of memory in order to free up main memory for other processes, swapping the process back in later when more memory is available, or when the process has been unblocked and is no longer waiting for a resource.

5. Which of the following scheduling algorithms is nonpreemptive? (GATE CS 2002) a) Round Robin b) First-In First-Out c) Multilevel Queue Scheduling d) Multilevel Queue Scheduling with Feedback Answer: (b)

Database Management Systems | Set 1


September 23, 2009

Following questions have been asked in GATE CS exam.

1. Given the relations employee (name, salary, deptno) and department (deptno, deptname, address) Which of the following queries cannot be expressed using the basic relational algebra operations (U, -, x, , p)? (GATE CS 2000) (a) Department address of every employee (b) Employees whose name is the same as their department name (c) The sum of all employees salaries (d) All employees of a given department Answer: (c) Explanation: The six basic operators of relational algebra are the selection( ), the projection( ), the Cartesian product (x) (also called the cross product or cross join), the set union (U), the set difference (-), and the rename (p). These six operators are fundamental in the sense that none of them can be omitted without losing expressive power. Many other operators have been defined in terms of these six. Among the most important are set intersection, division, and the natural join, but aggregation is not possible with these basic relational algebra operations. So, we cannot run sum of all employees salaries with the six operations. References: http://en.wikipedia.org/wiki/Relational_algebra http://faculty.ksu.edu.sa/zitouni/203%20Haseb%20%20Lecture%20N otes/Relional%20Algebra.pdf

2. Given the following relation instance.

x 1

y 4

z 2

1 1 3

5 6 2

3 3 2

Which of the following functional dependencies are satisfied by the instance? (GATE CS 2000) (a) XY -> Z and Z -> Y (b) YZ -> X and Y -> Z (c) YZ -> X and X -> Z (d) XZ -> Y and Y -> X Answer: (b) Explanation: A functional dependency (FD) is a constraint between two sets of attributes in a relation from a database. A FD X->Y require that the value of X uniquely determines the value of Y where X and Y are set of attributes. FD is a generalization of the notion of a key. Given that X, Y, and Z are sets of attributes in a relation R, one can derive several properties of functional dependencies. Among the most important are Armstrongs axioms, which are used in database normalization:

* Subset Property (Axiom of Reflexivity): If Y is a subset of X, then X ? Y * Augmentation (Axiom of Augmentation): If X -> Y, then XZ -> YZ * Transitivity (Axiom of Transitivity): If X -> Y and Y -> Z, then X -> Z
From these rules, we can derive these secondary rules:

* Union: If X -> Y and X -> Z, then X -> YZ * Decomposition: If X -> YZ, then X -> Y and X -> Z * Pseudotransitivity: If X -> Y and YZ -> W, then XZ -> W

In the above question, Y uniquely determines X and Z, for a given value of Y you can easily find out values of X and Z. So, Y -> X and Y -> Z hold for above schema. From rule of augmentation we can say YZ->X. If we understand the notion of FD, we dont need to apply axioms to find out which option is true, just by looking at the schema and options we can say that (b) is true. References: http://www.cse.iitb.ac.in/~sudarsha/db-book/slide-dir/ch7.pdf http://en.wikipedia.org/wiki/Functional_dependency

3. Given relations r(w, x) and s(y, z), the result of select distinct w, x from r, s is guaranteed to be same as r, provided (GATE CS 2000) (a) r has no duplicates and s is non-empty (b) r and s have no duplicates (c) s has no duplicates and r is non-empty (d) r and s have the same number of tuples Answer: (a) Explanation: The query selects all attributes of r. Since we have distinct in query, result can be equal to r only if r doesnt have duplicates. If we do not give any attribute on which we want to join two tables, then the queries like above become equivalent to Cartesian product. Cartisian product of two sets will be empty if any of the two sets is empty. So, s should have atleast one record to get all rows of r.

4. In SQL, relations can contain null values, and comparisons with null values are treated as unknown. Suppose all

comparisons with a null value are treated as false. Which of the following pairs is not equivalent? (GATE CS 2000) (a) x = 5, not (not (x = 5) (b) x = 5, x > 4 and x < 6, where x is an integer (c) x < 5, not(x = 5) (d) None of the above Answer (c) Explanation: It doesnt need much explanation. For all values smaller than 5, x < 5 will always be true but x = 5 will be false.

5. Consider a schema R(A, B, C, D) and functional dependencies A -> B and C -> D. Then the decomposition of R into R1 (A, B) and R2(C, D) is (GATE CS 2001) a) dependency preserving and loss less join b) loss less join but not dependency preserving c) dependency preserving but not loss less join d) not dependency preserving and not loss less join Answer: (c) Explanation: Dependency Preserving Decomposition: Decomposition of R into R1 and R2 is a dependency preserving decomposition if closure of functional dependencies after decomposition is same as closure of of FDs before decomposition. A simple way is to just check whether we can derive all the original FDs from the FDs present after decomposition. In the above question R(A, B, C, D) is decomposed into R1 (A, B) and R2(C, D) and there are only two FDs A -> B and C -> D. So, the decomposition is dependency preserving Lossless-Join Decomposition: Decomposition of R into R1 and R2 is a lossless-join decomposition if

at least one of the following functional dependencies are in F+ (Closure of functional dependencies)

R1 OR R1

R2 R2

R1 R2

In the above question R(A, B, C, D) is decomposed into R1 (A, B) and R2(C, D), and R1 R2 is empty. So, the decomposition is not lossless. References: http://www.cs.sfu.ca/CC/354/han/materia/notes/354noteschapter6/node1.html

Median of two sorted arrays


September 28, 2009

Question: There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The complexity should be O(log(n)) Median: In probability theory and statistics, a median is described as the number separating the higher half of a sample, a population, or a probability distribution, from the lower half. The median of a finite list of numbers can be found by arranging all the numbers from lowest value to highest value and picking the middle one. For getting the median of input array { 12, 11, 15, 10, 20 }, first sort the array. We get { 10, 11, 12, 15, 20 } after sorting. Median is the middle element of the sorted array which is 12. There are different conventions to take median of an array with even number of elements, one can take the mean of the two middle values, or first middle value, or second middle value. Let us see different methods to get the median of two sorted arrays of size n each. Since size of the set for which we are looking for median

is even (2n), we are taking average of middle two numbers in all below solutions. Method 1 (Simply count while Merging) Use merge procedure of merge sort. Keep track of count while comparing elements of two arrays. If count becomes n(For 2n elements), we have reached the median. Take the average of the elements at indexes n-1 and n in the merged array. See the below implementation. Implementation:
#include <stdio.h> /* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { int i = 0; /* Current index of i/p array ar1[] */ int j = 0; /* Current index of i/p array ar2[] */ int count; int m1 = -1, m2 = -1; /* Since there are 2n elements, median will be average of elements at index n-1 and n in the array obtained after merging ar1 and ar2 */ for (count = 0; count <= n; count++) { /*Below is to handle case where all elements of ar1[] are smaller than smallest(or first) element of ar2[]*/ if (i == n) { m1 = m2; m2 = ar2[0]; break; } /*Below is to handle case where all elements of ar2[] are smaller than smallest(or first) element of ar1[]*/ else if (j == n) { m1 = m2; m2 = ar1[0]; break; } if (ar1[i] < ar2[j]) { m1 = m2; /* Store the prev median */ m2 = ar1[i]; i++; }

else { m1 = m2; /* Store the prev median */ m2 = ar2[j]; j++; } } return (m1 + m2)/2; } /* Driver program to test above function */ int main() { int ar1[] = {1, 12, 15, 26, 38}; int ar2[] = {2, 13, 17, 30, 45}; int n1 = sizeof(ar1)/sizeof(ar1[0]); int n2 = sizeof(ar2)/sizeof(ar2[0]); if (n1 == n2) printf("Median is %d", getMedian(ar1, ar2, n1)); else printf("Doesn't work for arrays of unequal size"); getchar(); return 0; }

Time Complexity: O(n)

Method 2 (By comparing the medians of two arrays) This method works by first getting medians of the two sorted arrays and then comparing them. Let ar1 and ar2 be the input arrays. Algorithm:

1) Calculate the medians m1 and m2 of the input arrays ar1[] and ar2[] respectively. 2) If m1 and m2 both are equal then we are done. return m1 (or m2) 3) If m1 is greater than m2, then median is present in one of the below two subarrays.

a) From first element of ar1 to m1 (ar1[0...|_n/2_|]) b) From m2 to last element of ar2 (ar2[|_n/2_|...n-1]) 4) If m2 is greater than m1, then median is present in one of the below two subarrays. a) From m1 to last element of ar1 (ar1[|_n/2_|...n-1]) b) From first element of ar2 to m2 (ar2[0...|_n/2_|]) 5) Repeat the above process until size of both the subarrays becomes 2. 6) If size of the two arrays is 2 then use below formula to get the median. Median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2
Example:

ar1[] = {1, 12, 15, 26, 38} ar2[] = {2, 13, 17, 30, 45}
For above two arrays m1 = 15 and m2 = 17 For the above ar1[] and ar2[], m1 is smaller than m2. So median is present in one of the following two subarrays.

[15, 26, 38] and [2, 13, 17]


Let us repeat the process for above two subarrays:

m1 = 26 m2 = 13.
m1 is greater than m2. So the subarrays become

[15, 26] and [13, 17]

Now size is 2, so median + min(ar1[1], ar2[1]))/2 = 17))/2 = =


Implementation:
#include<stdio.h>

= (max(ar1[0], ar2[0]) (max(15, 13) + min(26, (15 + 17)/2 16

int max(int, int); /* to get maximum of two integers */ int min(int, int); /* to get minimum of two integeres */ int median(int [], int); /* to get median of a sorted array */ /* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { int m1; /* For median of ar1 */ int m2; /* For median of ar2 */ /* return -1 for invalid input */ if (n <= 0) return -1; if (n == 1) return (ar1[0] + ar2[0])/2; if (n == 2) return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2; m1 = median(ar1, n); /* get the median of the first array */ m2 = median(ar2, n); /* get the median of the second array */ /* If medians are equal then return either m1 or m2 */ if (m1 == m2) return m1; /* if m1 < m2 then median must exist in ar1[m1....] and ar2[....m2] */ if (m1 < m2) { if (n % 2 == 0) return getMedian(ar1 + n/2 - 1, ar2, n - n/2 +1); else return getMedian(ar1 + n/2, ar2, n - n/2); } /* if m1 > m2 then median must exist in ar1[....m1] and ar2[m2...] */ else {

if (n % 2 == 0) return getMedian(ar2 + n/2 - 1, ar1, n - n/2 + 1); else return getMedian(ar2 + n/2, ar1, n - n/2); } } /* Function to get median of a sorted array */ int median(int arr[], int n) { if (n%2 == 0) return (arr[n/2] + arr[n/2-1])/2; else return arr[n/2]; } /* Driver program to test above function */ int main() { int ar1[] = {1, 2, 3, 6}; int ar2[] = {4, 6, 8, 10}; int n1 = sizeof(ar1)/sizeof(ar1[0]); int n2 = sizeof(ar2)/sizeof(ar2[0]); if (n1 == n2) printf("Median is %d", getMedian(ar1, ar2, n1)); else printf("Doesn't work for arrays of unequal size"); getchar(); return 0; } /* Utility functions */ int max(int x, int y) { return x > y? x : y; } int min(int x, int y) { return x > y? y : x; }

Time Complexity: O(logn) Algorithmic Paradigm: Divide and Conquer

Method 3 (By doing binary search for the median): The basic idea is that if you are given two arrays ar1[] and ar2[] and know the length of each, you can check whether an element ar1[i] is the median in constant time. Suppose that the median is ar1[i]. Since the array is sorted, it is greater than exactly i values in array ar1[].

Then if it is the median, it is also greater than exactly j = n i 1 elements in ar2[]. It requires constant time to check if ar2[j] <= ar1[i] <= ar2[j + 1]. If ar1[i] is not the median, then depending on whether ar1[i] is greater or less than ar2[j] and ar2[j + 1], you know that ar1[i] is either greater than or less than the median. Thus you can binary search for median in O(lg n) worst-case time. For two arrays ar1 and ar2, first do binary search in ar1[]. If you reach at the end (left or right) of the first array and don't find median, start searching in the second array ar2[].

1) Get the middle element of ar1[] using array indexes left and right. Let index of the middle element be i. 2) Calculate the corresponding index j of ar2[] j = n i 1 3) If ar1[i] >= ar2[j] and ar1[i] <= ar2[j+1] then ar1[i] and ar2[j] are the middle elements. return average of ar2[j] and ar1[i] 4) If ar1[i] is greater than both ar2[j] and ar2[j+1] then do binary search in left half (i.e., arr[left ... i-1]) 5) If ar1[i] is smaller than both ar2[j] and ar2[j+1] then do binary search in right half (i.e., arr[i+1....right]) 6) If you reach at any corner of ar1[] then do binary search in ar2[]
Example:

ar1[] = {1, 5, 7, 10, 13} ar2[] = {11, 15, 23, 30, 45}
Middle element of ar1[] is 7. Let us compare 7 with 23 and 30, since 7 smaller than both 23 and 30, move to right in ar1[]. Do binary search

in {10, 13}, this step will pick 10. Now compare 10 with 15 and 23. Since 10 is smaller than both 15 and 23, again move to right. Only 13 is there in right side now. Since 13 is greater than 11 and smaller than 15, terminate here. We have got the median as 12 (average of 11 and 13) Implementation:
#include<stdio.h> int getMedianRec(int ar1[], int ar2[], int left, int right, int n); /* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { return getMedianRec(ar1, ar2, 0, n-1, n); } /* A recursive function to get the median of ar1[] and ar2[] using binary search */ int getMedianRec(int ar1[], int ar2[], int left, int right, int n) { int i, j; /* We have reached at the end (left or right) of ar1[] */ if(left > right) return getMedianRec(ar2, ar1, 0, n-1, n); i = (left + right)/2; j = n - i - 1; /* Index of ar2[] */ /* Recursion terminates here.*/ if (ar1[i] > ar2[j] && (j == n-1 || ar1[i] <= ar2[j+1])) { /*ar1[i] is decided as median 2, now select the median 1 (element just before ar1[i] in merged array) to get the average of both*/ if (ar2[j] > ar1[i-1] || i == 0) return (ar1[i] + ar2[j])/2; else return (ar1[i] + ar1[i-1])/2; } /*Search in left half of ar1[]*/ else if (ar1[i] > ar2[j] && j != n-1 && ar1[i] > ar2[j+1]) return getMedianRec(ar1, ar2, left, i-1, n); /*Search in right half of ar1[]*/ else /* ar1[i] is smaller than both ar2[j] and ar2[j+1]*/ return getMedianRec(ar1, ar2, i+1, right, n); }

/* Driver program to test above function */ int main() { int ar1[] = {1, 12, 15, 26, 38}; int ar2[] = {2, 13, 17, 30, 45}; int n1 = sizeof(ar1)/sizeof(ar1[0]); int n2 = sizeof(ar2)/sizeof(ar2[0]); if (n1 == n2) printf("Median is %d", getMedian(ar1, ar2, n1)); else printf("Doesn't work for arrays of unequal size"); getchar(); return 0; }

Time Complexity: O(logn) Algorithmic Paradigm: Divide and Conquer The above solutions can be optimized for the cases when all elements of one array are smaller than all elements of other array. For example, in method 3, we can change the getMedian() function to following so that these cases can be handled in O(1) time. Thanks to nutcracker for suggesting this optimization.
/* This function returns median of ar1[] and ar2[]. Assumptions in this function: Both ar1[] and ar2[] are sorted arrays Both have n elements */ int getMedian(int ar1[], int ar2[], int n) { // If all elements of array 1 are smaller then // median is average of last element of ar1 and // first element of ar2 if (ar1[n-1] < ar2[0]) return (ar1[n-1]+ar2[0])/2; // // // if If all elements of array 1 are smaller then median is average of first element of ar1 and last element of ar2 (ar2[n-1] < ar1[0]) return (ar2[n-1]+ar1[0])/2;

return getMedianRec(ar1, ar2, 0, n-1, n); }

References: http://en.wikipedia.org/wiki/Median http://ocw.alfaisal.edu/NR/rdonlyres/Electrical-Engineering-andComputer-Science/6-046JFall-2005/30C68118-E436-4FE3-8C796BAFBB07D935/0/ps9sol.pdf ds3etph5wn

C Language | Set 1
October 3, 2009

Following questions have been asked in GATE CS exam. 1. Consider the following three C functions :
[PI] int * g (void) { int x = 10; return (&x); }

[P2] int * g (void) { int * px; *px = 10; return px; }

[P3] int *g (void) { int *px; px = (int *) malloc (sizeof(int)); *px = 10; return px; }

Which of the above three functions are likely to cause problems with pointers? (GATE 2001) (a) Only P3 (b) Only P1 and P3

(c) Only P1 and P2 (d) P1, P2 and P3 Answer: (c) Eplaination: In P1, variable x is a local variable to g(), and g() returns address of this variable. x will vanish after g() has returned as x exists on stack. So, &x will become a dangling pointer. In P2, pointer variable px is being assigned a value without allocating memory to it. P3 works perfectly fine. Memory is allocated to pointer variable px using malloc(). So, px exists on heap, its existence will remain in memory even after return of g() as it is on heap.

2. The value of j at the end of the execution of the following C program. (GATE CS 2000)
int incr (int i) { static int count = 0; count = count + i; return (count); } main () { int i,j; for (i = 0; i <=4; i++) j = incr(i); }

(a) 10 (b) 4 (c) 6 (d) 7

Answer (a) Eplaination: count is static variable in incr(). Statement static int count = 0 will assign count to 0 only in first call. Other calls to this function will take the old values of count. Count will become 0 after the call incr(0) Count will become 1 after the call incr(1) Count will become 3 after the call incr(2) Count will become 6 after the call incr(3) Count will become 10 after the call incr(4)

3. Consider the following C declaration


struct { short s [5] union { float y; long z; }u; } t;

Assume that objects of the type short, float and long occupy 2 bytes, 4 bytes and 8 bytes, respectively. The memory requirement for variable t, ignoring alignment considerations, is (GATE CS 2000) (a) 22 bytes (b) 14 bytes (c) 18 bytes (d) 10 bytes Answer: (c) Explanation: Short array s[5] will take 10 bytes as size of short is 2 bytes. Since u is a union, memory allocated to u will be max of float y(4 bytes) and long z(8 bytes). So, total size will be 18 bytes (10 + 8).

4. The number of tokens in the following C statement.


printf("i = %d, &i = %x", i, &i);

is (GATE 2000) (a) 3 (b) 26 (c) 10 (d) 21 Answer (c) Explanation:In a C source program, the basic element recognized by the compiler is the token. A token is source-program text that the compiler does not break down into component elements. There are 6 types of C tokens : identifiers, keywords, constants, operators, string literals and other separators. There are total 10 tokens in the above printf statement.

5. The following C declarations


struct node { int i; float j; }; struct node *s[10] ;

define s to be (GATE CS 2000) (a) An array, each element of which is a pointer to a structure of type node (b) A structure of 2 fields, each field being a pointer to an array of 10 elements

(c) A structure of 3 fields: an integer, a float, and an array of 10 elements (d) An array, each element of which is a structure of type node. Answer: (a)

Compiler Theory | Set 1


October 4, 2009

Following questions have been asked in GATE CS exam. 1. Which of the following derivations does a top-down parser use while parsing an input string? The input is assumed to be scanned in left to right order (GATE CS 2000). (a) Leftmost derivation (b) Leftmost derivation traced out in reverse (c) Rightmost derivation (d) Rightmost derivation traced out in reverse Answer (a) Top-down parsing (LL) In top down parsing, we just start with the start symbol and compare the right side of the different productions against the first piece of input to see which of the productions should be used. A top down parser is called LL parser because it parses the input from Left to right, and constructs aLeftmost derivation of the sentence. Algorithm (Top Down Parsing)

a) In the current string, choose leftmost nonterminal. b) Choose a production for the chosen nonterminal. c) In the string, replace the nonterminal by the right-hand-side of the rule. d) Repeat until no more nonterminals.

LL grammars are often classified by numbers, such as LL(1), LL(0) and so on. The number in the parenthesis tells the maximum number of terminals we may have to look at at a time to choose the right production at any point in the grammar. The most common (and useful) kind of LL grammar is LL(1) where you can always choose the right production by looking at only the first terminal on the input at any given time. With LL(2) you have to look at two symbols, and so on. There exist grammars that are not LL(k) grammars for any fixed value of k at all, and they are sadly quite common. Let us see an example of top down parsing for following grammar. Let input string be ax.

S -> Ax A -> a A -> b


An LL(1) parser starts with S and asks which production should I attempt? Naturally, it predicts the only alternative of S. From there it tries to match A by calling method A (in a recursive-descent parser). Lookahead a predicts production

A -> a
The parser matches a, returns to S and matches x. Done. The derivation tree is:

S / \ A | a x

References: http://www.garshol.priv.no/download/text/bnf.html http://en.wikipedia.org/wiki/Top-down_parsing http://www.cs.wm.edu/~noonan/animations/lderive.html http://en.wikipedia.org/wiki/LL_parser

2. The process of assigning load addresses to the various parts of the program and adjusting the code and data in the program to reflect the assigned addresses is called (GATE CS 2001) a) Assembly b) Parsing c) Relocation d) Symbol resolution Answer: (c) Relocation is the process of replacing symbolic references or names of libraries with actual usable addresses in memory before running a program. It is typically done by the linker during compilation (at compile time), although it can be done at runtime by a relocating loader. Compilers or assemblers typically generate the executable with zero as the lower-most starting address. Before the execution of object code, these addresses should be adjusted so that they denote the correct runtime addresses. Relocation is typically done in two steps: 1. Each object code has various sections like code, data, .bss etc. To combine all the objects to a single executable, the linker merges all sections of similar type into a single section of that type. The linker then assigns runtime addresses to each section and each symbol. At this point, the code (functions) and data (global variables) will have unique runtime addresses. 2. Each section refers to one or more symbols which should be modified so that they point to the correct runtime addresses. References: http://en.wikipedia.org/wiki/Relocation_(computer_science)

3. Which of the following statements is false? (GATE CS 2001) a) An unambiguous grammar has same leftmost and rightmost

derivation b) An LL(1) parser is a top-down parser c) LALR is more powerful than SLR d) An ambiguous grammar can never be LR(k) for any k Answer: (a) If a grammar has more than one leftmost (or rightmost) derivation for a single sentential form, the grammar is ambiguous. The leftmost and rightmost derivations for a sentential form may differ, even in an unambiguous grammar 4. Which of the following grammar rules violate the requirements of an operator grammar? P, Q, R are nonterminals, and r,s,t are terminals (GATE CS 2004). (i) P -> QR (ii) P -> QsR (iii) P -> (iV) P -> QtRr a) (i) only b) (i) and (iii) only c) (ii) and (iii) only d) (iii) and (iv) only Answer: (b) Explanation: An operator precedence parser is a bottom-up parser that interprets an operator-precedence grammar. For example, most calculators use operator precedence parsers to convert from the human-readable infix notation with order of operations format into an internally optimized computer-readable format like Reverse Polish notation (RPN). An operator precedence grammar is a kind of context-free grammar that can be parsed with an operator-precedence parser. It has the property that no production has either an empty ( ) right-hand side or two adjacent nonterminals in its right-hand side. These properties allow the terminals of the grammar to be described by a precedence relation, and the a parser that exploits that relation is considerably simpler than more general-purpose parsers such as LALR parsers.

References: http://en.wikipedia.org/wiki/Operator-precedence_grammar http://en.wikipedia.org/wiki/Operator-precedence_parser

5. Consider the grammar with the following translation rules and E as the start symbol. E -> E1 #T {E.value = E1.value * T.value} | T {E.value = T.value} T -> T1 & F {T.value = T1.value + F.value} |F {T.value= F.value} F -> num {F.value = num.value} Compute E.value for the root of the parse tree for the expression:2 # 3 & 5 # 6 &4. (GATE CS 2004) a) 200 b) 180 c) 160 d) 40 Answer: (c) Explanation: We can calculate the value by constructing the parse tree for the expression 2 # 3 & 5 # 6 &4. Alternatively, we can calculate by considering following precedence and associativity rules. Precedence in a grammar is enforced by making sure that a production rule with higher precedence operator will never produce an expression with operator with lower precedence. In the given grammar & has higher precedence than #. Left associativity for operator * in a grammar is enforced by making sure that for a production rule like S -> S1 * S2 in grammar, S2 should never produce an expression with *. On the other hand, to ensure right associativity, S1 should never produce an expression with *. In the given grammar, both # and & are left-associative.

So expression 2 # 3 & 5 # 6 &4 will become ((2 # (3 & 5)) # (6 & 4)) Let us apply translation rules, we get ((2 * (3 + 5)) * (6 + 4)) = 160.

Data Structures and Algorithms | Set 1


October 6, 2009

Following questions have been asked in GATE CS exam 1. Let LASTPOST, LASTIN and LASTPRE denote the last vertex visited in a postorder, inorder and preorder traversal. Respectively, of a complete binary tree. Which of the following is always true? (GATE CS 2000) (a) LASTIN = LASTPOST (b) LASTIN = LASTPRE (c) LASTPRE = LASTPOST (d) None of the above Answer (d) It is given that the given tree is complete binary tree. For a complete binary tree, the last visited node will always be same for inorder and preorder traversal. None of the above is true even for a complete binary tree. The option (a) is incorrect because the last node visited in Inorder traversal is right child and last node visited in Postorder traversal is root. The option (c) is incorrect because the last node visited in Preorder traversal is right child and last node visited in Postorder traversal is root. For option (b), see the following counter example. Thanks to Hunaif Muhammed for providing the correct explanation.

1 / 2 \ 3

/ \ 4 5 6

Inorder traversal is 4 2 5 1 6 3 Preorder traversal is 1 2 4 5 3 6

2. The most appropriate matching for the following pairs

X: depth first search Y: breadth-first search Z: sorting


is (GATE CS 2000): (a) X1 Y2 Z-3 (b) X3 Y1 Z-2 (c) X3 Y2 Z-1 (d) X2 Y3 Z-1 Answer: (c) Stack is used for Depth first Search Queue is used for Breadth First Search Heap is used for sorting

1: heap 2: queue 3: stack

3. Consider the following nested representation of binary trees: (X Y Z) indicates Y and Z are the left and right sub stress, respectively, of node X. Note that Y and Z may be NULL, or further nested. Which of the following represents a valid binary tree? (a) (1 2 (4 5 6 7)) (b) (1 (2 3 4) 5 6) 7) (c) (1 (2 3 4)(5 6 7)) (d) (1 (2 3 NULL) (4 5)) Answer (c)

4. Let s be a sorted array of n integers. Let t(n) denote the time taken for the most efficient algorithm to determined if there are two elements with sum less than 1000 in s. which of the following statements is true? (GATE CS 2000) a) t (n) is 0 (1) b) n < t (n) < n c) n log 2 n < t (n) < d) t (n) = Answer (a) Let array be sorted in ascending order, if sum of first two elements is less than 1000 then there are two elements with sum less than 1000 otherwise not. For array sorted in descending order we need to check last two elements. For an array data structure, number of operations are fixed in both the cases and not dependent on n, complexity is O(1)

5. B+ trees are preferred to binary trees in databases because (GATE CS 2000) (a) Disk capacities are greater than memory capacities (b) Disk access is much slower than memory access (c) Disk data transfer rates are much less than memory data transfer rates (d) Disks are more reliable than memory Answer (b) Disk access is slow and B+ Tree provide search in less number of disk hits. This is primarily because unlike binary seach trees, B+ trees have very high fanout (typically on the order of 100 or more), which reduces the number of I/O operations required to find an element in the tree.

C Language | Set 2
October 7, 2009

Following questions have been asked in GATE CS exam.

1. Consider the following C program segment:


char p[20]; char *s = "string"; int length = strlen(s); int i; for (i = 0; i < length; i++) p[i] = s[length i]; printf("%s",p);

The output of the program is (GATE CS 2004) a) gnirts b) gnirt c) string d) no output is printed Answer(d) Let us consider below line inside the for loop p[i] = s[length i]; For i = 0, p[i] will be s[6 0] and s[6] is \0 So p[0] becomes \0. It doesnt matter what comes in p[1], p[2].. as P[0] will not change for i >0. Nothing is printed if we print a string with first character \0

2. Consider the following C function


void swap (int a, int b) { int temp; temp = a; a = b; b = temp;

In order to exchange the values of two variables x and y. (GATE CS 2004) a) call swap (x, y) b) call swap (&x, &y) c) swap (x,y) cannot be used as it does not return any value d) swap (x,y) cannot be used as the parameters are passed by value Answer(d) Why a, b and c are incorrect? a) call swap (x, y) will not cause any effect on x and y as parameters are passed by value. b) call swap (&x, &y) will no work as function swap() expects values not addresses (or pointers). c) swap (x, y) cannot be used but reason given is not correct.

3. Consider the following C function:


int f(int n) { static int i = 1; if (n >= 5) return n; n = n+i; i++; return f(n); }

The value returned by f(1) is (GATE CS 2004) a) 5 b) 6 c) 7 d) 8

Answer (c) Since i is static, first line of f() is executed only once.

Execution of f(1) i = 1 n = 2 i = 2 Call f(2) i = 2 n = 4 i = 3 Call f(4) i = 3 n = 7 i = 4 Call f(7) since n >= 5 return n(7)

4. Consider the following program fragment for reversing the digits in a given integer to obtain a new integer. Let n = D1D2Dm
int n, rev; rev = 0; while (n > 0) { rev = rev*10 + n%10; n = n/10; }

The loop invariant condition at the end of the ith iteration is:(GATE CS 2004)

a) n = D1D2.Dm-i and rev = DmDm-1Dm-i+1 b) n = Dm-i+1Dm-1Dm and rev = Dm-1.D2D1 c) n rev d) n = D1D2.Dm and rev = DmDm-1D2D1 Answer (a)

5. Consider the following C program


main() { int x, y, m, n; scanf ("%d %d", &x, &y); /* x > 0 and y > 0 */ m = x; n = y; while (m != n) { if(m>n) m = m - n; else n = n - m; } printf("%d", n); }

The program computes (GATE CS 2004) a) x + y using repeated subtraction b) x mod y using repeated subtraction c) the greatest common divisor of x and y d) the least common multiple of x and y

Answer(c) This is an implementation of Euclids algorithm to find GCD

Write a function to get the intersection point of two Linked Lists.


October 10, 2009
There are two singly linked lists in a system. By some programming error the end node of one of the linked list got linked into the second list, forming a inverted Y shaped list. Write a program to get the point where two linked list merge.

Above diagram shows an example with two linked list having 15 as intersection point. Method 1(Simply use two loops) Use 2 nested for loops. Outer loop will be for each node of the 1st list and inner loop will be for 2nd list. In the inner loop, check if any of nodes of 2nd list is same as the current node of first linked list. Time complexity of this method will be O(mn) where m and n are the number of nodes in two lists. Method 2 (Mark Visited Nodes) This solution requires modifications to basic linked list data structure. Have a visited flag with each node. Traverse the first linked list and keep marking visited nodes. Now traverse second linked list, If you see a visited node again then there is an intersection point, return the intersecting node. This solution works in O(m+n) but requires additional information with each node. A variation of this solution that doesnt require modification to basic data structure can be implemented using hash. Traverse the first linked list and store the addresses of visited nodes in a hash. Now traverse the second linked list and if you see an address that already exists in hash then return the intersecting node. Method 3(Using difference of node counts) 1) Get count of the nodes in first list, let count be c1.

2) Get count of the nodes in second list, let count be c2. 3) Get the difference of counts d = abs(c1 c2) 4) Now traverse the bigger list from the first node till d nodes so that from here onwards both the lists have equal no of nodes. 5) Then we can traverse both the lists in parallel till we come across a common node. (Note that getting a common node is done by comparing the address of the nodes) #include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to get the counts of node in a linked list */ int getCount(struct node* head);

/* function to get the intersection point of two linked lists head1 and head2 where head1 has d more nodes than head2 */ int _getIntesectionNode(int d, struct node* head1, struct node* head2);

/* function to get the intersection point of two linked lists head1 and head2 */ int getIntesectionNode(struct node* head1, struct node* head2) { int c1 = getCount(head1); int c2 = getCount(head2); int d;

if(c1 > c2) { d = c1 - c2; return _getIntesectionNode(d, head1, head2); } else { d = c2 - c1; return _getIntesectionNode(d, head2, head1); } }

/* function to get the intersection point of two linked lists head1 and head2 where head1 has d more nodes than head2 */ int _getIntesectionNode(int d, struct node* head1, struct node* head2) { int i; struct node* current1 = head1; struct node* current2 = head2;

for(i = 0; i < d; i++) { if(current1 == NULL) { return -1; }

current1 = current1->next; }

while(current1 != {

NULL && current2 != NULL)

if(current1 == current2) return current1->data; current1= current1->next; current2= current2->next; }

return -1; }

/* Takes head pointer of the linked list and returns the count of nodes in the list */ int getCount(struct node* head) { struct node* current = head; int count = 0;

while (current != NULL) { count++; current = current->next; }

return count; }

/* IGNORE THE BELOW LINES OF CODE. THESE LINES ARE JUST TO QUICKLY TEST THE ABOVE FUNCTION */

int main() { /* Create two linked lists

1st 3->6->9->15->30 2nd 10->15->30

15 is the intersection point */

struct node* newNode; struct node* head1 = (struct node*) malloc(sizeof(struct node)); head1->data = 10;

struct node* head2 = (struct node*) malloc(sizeof(struct node)); head2->data = 3;

newNode = (struct node*) malloc (sizeof(struct node)); newNode->data = 6; head2->next = newNode;

newNode = (struct node*) malloc (sizeof(struct node)); newNode->data = 9; head2->next->next = newNode;

newNode = (struct node*) malloc (sizeof(struct node));

newNode->data = 15; head1->next = newNode; head2->next->next->next = newNode;

newNode = (struct node*) malloc (sizeof(struct node)); newNode->data = 30; head1->next->next= newNode;

head1->next->next->next = NULL;

printf("\n The node of intersection is %d \n", getIntesectionNode(head1, head2));

getchar(); }

Time Complexity: O(m+n) Auxiliary Space: O(1) Method 4(Make circle in first list) Thanks to Saravanan Man for providing below solution. 1. Traverse the first linked list(count the elements) and make a circular linked list. (Remember last node so that we can break the circle later on). 2. Now view the problem as find the loop in the second linked list. So the problem is solved. 3. Since we already know the length of the loop(size of first linked list) we can traverse those many number of nodes in second list, and then start another pointer from the beginning of second list. we have to traverse until they are equal, and that is the required intersection point. 4. remove the circle from the linked list. Time Complexity: O(m+n) Auxiliary Space: O(1) Method 5 (Reverse the first list and make equations) Thanks to Saravanan Mani for providing this method.

1) Let X be the length of the first linked list until intersection point.

Let Y be the length of the second linked list until the intersection point. Let Z be the length of the linked list from intersection point to End of the linked list including the intersection node. We Have X + Z = C1; Y + Z = C2; 2) Reverse first linked list. 3) Traverse Second linked list. Let C3 be the length of second list - 1. Now we have X + Y = C3 We have 3 linear equations. By solving them, we get X = (C1 + C3 C2)/2; Y = (C2 + C3 C1)/2; Z = (C1 + C2 C3)/2; WE GOT THE INTERSECTION POINT. 4) Reverse first linked list.
Advantage: No Comparison of pointers. Disadvantage : Modifying linked list(Reversing list). Time complexity: O(m+n) Auxiliary Space: O(1) Method 6 (Traverse both lists and compare addresses of last nodes) This method is only to detect if there is an intersection point or not. (Thanks to NeoTheSaviour for suggesting this)

1) Traverse the list 1, store the last node address 2) Traverse the list 2, store the last node address. 3) If nodes stored in 1 and 2 are same then they are intersecting.
Time complexity of this method is O(m+n) and used Auxiliary space is O(1)

Find the two non-repeating elements in an array of repeating elements


October 21, 2009

Asked by SG Given an array in which all numbers except two are repeated once. (i.e. we have 2n+2 numbers and n numbers are occurring twice and remaining two have occurred once). Find those two numbers in the most efficient way. Method 1(Use Sorting) First sort all the elements. In the sorted array, by comparing adjacent elements we can easily get the non-repeating elements. Time complexity of this method is O(nLogn) Method 2(Use XOR) Let x and y be the non-repeating elements we are looking for and arr[] be the input array. First calculate the XOR of all the array elements.

xor = arr[0]^arr[1]^arr[2].....arr[n-1]
All the bits that are set in xor will be set in one non-repeating element (x or y) and not in other. So if we take any set bit of xor and divide the elements of the array in two sets one set of elements with same bit set and other set with same bit not set. By doing so, we will get x in one set and y in another set. Now if we do XOR of all the elements in first set, we will get first non-repeating element, and by doing same in other set we will get the second non-repeating element.

Let us see an example. arr[] = {2, 4, 7, 9, 2, 4} 1) Get the XOR of all the elements. xor = 2^4^7^9^2^4 = 14 (1110) 2) Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it. set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010

Now set_bit_no will have only set as rightmost set bit of xor. 3) Now divide the elements in two sets and do xor of elements in each set, and we get the nonrepeating elements 7 and 9. Please see implementation for this step.
Implementation:
#include <stdio.h> #include <stdlib.h>

/* This finction sets the values of *x and *y to nonr-epeating elements in an array arr[] of size n*/ void get2NonRepeatingNos(int arr[], int n, int *x, int *y) { int xor = arr[0]; /* Will hold xor of all elements */ int set_bit_no; int i; *x = 0; *y = 0; /* Will have only single set bit of xor */

/* Get the xor of all elements */ for(i = 1; i < n; i++) xor ^= arr[i];

/* Get the rightmost set bit in set_bit_no */ set_bit_no = xor & ~(xor-1);

/* Now divide elements in two sets by comparing rightmost set bit of xor with bit at same position in each element. */ for(i = 0; i < n; i++) { if(arr[i] & set_bit_no) *x = *x ^ arr[i]; /*XOR of first set */ else *y = *y ^ arr[i]; /*XOR of second set*/ } }

/* Driver program to test above function */ int main() { int arr[] = {2, 3, 7, 9, 11, 2, 3, 11}; int *x = (int *)malloc(sizeof(int)); int *y = (int *)malloc(sizeof(int)); get2NonRepeatingNos(arr, 8, x, y); printf("The non-repeating elements are %d and %d", *x, *y); getchar(); }

Time Complexity: O(n) Auxiliary Space: O(1)

Find the two non-repeating elements in an array of repeating elements


October 21, 2009

Asked by SG Given an array in which all numbers except two are repeated once. (i.e. we have 2n+2 numbers and n numbers are occurring twice and

remaining two have occurred once). Find those two numbers in the most efficient way. Method 1(Use Sorting) First sort all the elements. In the sorted array, by comparing adjacent elements we can easily get the non-repeating elements. Time complexity of this method is O(nLogn) Method 2(Use XOR) Let x and y be the non-repeating elements we are looking for and arr[] be the input array. First calculate the XOR of all the array elements.

xor = arr[0]^arr[1]^arr[2].....arr[n-1]
All the bits that are set in xor will be set in one non-repeating element (x or y) and not in other. So if we take any set bit of xor and divide the elements of the array in two sets one set of elements with same bit set and other set with same bit not set. By doing so, we will get x in one set and y in another set. Now if we do XOR of all the elements in first set, we will get first non-repeating element, and by doing same in other set we will get the second non-repeating element.

Let us see an example. arr[] = {2, 4, 7, 9, 2, 4} 1) Get the XOR of all the elements. xor = 2^4^7^9^2^4 = 14 (1110) 2) Get a number which has only one set bit of the xor. Since we can easily get the rightmost set bit, let us use it. set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010 Now set_bit_no will have only set as rightmost set bit of xor. 3) Now divide the elements in two sets and do xor of elements in each set, and we get the nonrepeating

elements 7 and 9. Please see implementation for this step.


Implementation:
#include <stdio.h> #include <stdlib.h>

/* This finction sets the values of *x and *y to nonr-epeating elements in an array arr[] of size n*/ void get2NonRepeatingNos(int arr[], int n, int *x, int *y) { int xor = arr[0]; /* Will hold xor of all elements */ int set_bit_no; int i; *x = 0; *y = 0; /* Will have only single set bit of xor */

/* Get the xor of all elements */ for(i = 1; i < n; i++) xor ^= arr[i];

/* Get the rightmost set bit in set_bit_no */ set_bit_no = xor & ~(xor-1);

/* Now divide elements in two sets by comparing rightmost set bit of xor with bit at same position in each element. */ for(i = 0; i < n; i++) { if(arr[i] & set_bit_no)

*x = *x ^ arr[i]; /*XOR of first set */ else *y = *y ^ arr[i]; /*XOR of second set*/ } }

/* Driver program to test above function */ int main() { int arr[] = {2, 3, 7, 9, 11, 2, 3, 11}; int *x = (int *)malloc(sizeof(int)); int *y = (int *)malloc(sizeof(int)); get2NonRepeatingNos(arr, 8, x, y); printf("The non-repeating elements are %d and %d", *x, *y); getchar(); }

Time Complexity: O(n) Auxiliary Space: O(1)

Write a program to reverse an array


October 30, 2009

Iterative way: 1) Initialize start and end indexes. start = 0, end = n-1 2) In a loop, swap arr[start] with arr[end] and change start and end as follows. start = start +1; end = end 1
/* Function to reverse arr[] from start to end*/ void rvereseArray(int arr[], int start, int end) { int temp;

while(start < end) { temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; } }

/* Utility that prints out an array on a line */ void printArray(int arr[], int size) { int i; for (i=0; i < size; i++) printf("%d ", arr[i]);

printf("\n"); }

/* Driver function to test above functions */ int main() { int arr[] = {1, 2, 3, 4, 5, 6}; printArray(arr, 6); rvereseArray(arr, 0, 5); printf("Reversed array is \n"); printArray(arr, 6); getchar();

return 0; }

Time Complexity: O(n) Recursive Way: 1) Initialize start and end indexes start = 0, end = n-1 2) Swap arr[start] with arr[end] 3) Recursively call reverse for rest of the array.
/* Function to reverse arr[] from start to end*/ void rvereseArray(int arr[], int start, int end) { int temp; if(start >= end) return; temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; rvereseArray(arr, start+1, end-1); }

/* Utility that prints out an array on a line */ void printArray(int arr[], int size) { int i; for (i=0; i < size; i++) printf("%d ", arr[i]);

printf("\n"); }

/* Driver function to test above functions */ int main() { int arr[] = {1, 2, 3, 4, 5}; printArray(arr, 5); rvereseArray(arr, 0, 4); printf("Reversed array is \n"); printArray(arr, 5); getchar(); return 0; }

Time Complexity: O(n)

Rotate bits of a number


October 31, 2009

Bit Rotation: A rotation (or circular shift) is an operation similar to shift except that the bits that fall off at one end are put back to the other end. In left rotation, the bits that fall off at left end are put back at right end. In right rotation, the bits that fall off at right end are put back at left end. Example: Let n is stored using 8 bits. Left rotation of n = 11100101 by 3 makes n = 00101111 (Left shifted by 3 and first 3 bits are put back in last ). If n is stored using 16 bits or 32 bits then left rotation of n (00011100101) becomes 00..0011100101000. Right rotation of n = 11100101 by 3 makes n = 10111100 (Right shifted by 3 and last 3 bits are put back in first ) if n is stored using 8 bits. If n is stored using 16 bits or 32 bits then right rotation of n (00011100101) by 3 becomes 101000..0011100.

#include<stdio.h> #define INT_BITS 32

/*Function to left rotate n by d bits*/ int leftRotate(int n, unsigned int d) { /* In n<<d, last d bits are 0. To put first 3 bits of n at last, do bitwise or of n<<d with n >>(INT_BITS - d) */ return (n << d)|(n >> (INT_BITS - d)); }

/*Function to right rotate n by d bits*/ int rightRotate(int n, unsigned int d) { /* In n>>d, first d bits are 0. To put last 3 bits of at first, do bitwise or of n>>d with n <<(INT_BITS - d) */ return (n >> d)|(n << (INT_BITS - d)); }

/* Driver program to test above functions */ int main() { int n = 16; int d = 2; printf("Left Rotation of %d by %d is ", n, d); printf("%d", leftRotate(n, d)); printf("\nRight Rotation of %d by %d is ", n, d); printf("%d", rightRotate(n, d)); getchar();

Compute the minimum or maximum of two integers without branching


November 1, 2009

On some rare machines where branching is expensive, the below obvious approach to find minimum can be slow as it uses branching.
/* The obvious approach to find minimum (involves branching) */ int min(int x, int y) { return (x < y) ? x : y }

Below are the methods to get minimum(or maximum) without using branching. Typically, the obvious approach is best, though. Method 1(Use XOR and comparison operator) Minimum of x and y will be

y ^ ((x ^ y) & -(x < y))


It works because if x < y, then -(x < y) will be all ones, so r = y ^ (x ^ y) & ~0 = y ^ x ^ y = x. Otherwise, if x >= y, then -(x < y) will be all zeros, so r = y ^ ((x ^ y) & 0) = y. On some machines, evaluating (x < y) as 0 or 1 requires a branch instruction, so there may be no advantage. To find the maximum, use

x ^ ((x ^ y) & -(x < y));


#include<stdio.h>

/*Function to find minimum of x and y*/ int min(int x, int y) { return y ^ ((x ^ y) & -(x < y));

/*Function to find maximum of x and y*/ int max(int x, int y) { return x ^ ((x ^ y) & -(x < y)); }

/* Driver program to test above functions */ int main() { int x = 15; int y = 6; printf("Minimum of %d and %d is ", x, y); printf("%d", min(x, y)); printf("\nMaximum of %d and %d is ", x, y); printf("%d", max(x, y)); getchar(); }

Method 2(Use subtraction and shift) If we know that

INT_MIN <= (x - y) <= INT_MAX


, then we can use the following, which are faster because (x - y) only needs to be evaluated once. Minimum of x and y will be

y + ((x - y) & ((x - y) >>(sizeof(int) * CHAR_BIT - 1)))

This method shifts the subtraction of x and y by 31 (if size of integer is 32). If (x-y) is smaller than 0, then (x -y)>>31 will be 1. If (x-y) is greater than or equal to 0, then (x -y)>>31 will be 0. So if x >= y, we get minimum as y + (x-y)&0 which is y. If x < y, we get minimum as y + (x-y)&1 which is x. Similarly, to find the maximum use

x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)))


#include<stdio.h> #define CHAR_BIT 8

/*Function to find minimum of x and y*/ int min(int x, int y) { return y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); }

/*Function to find maximum of x and y*/ int max(int x, int y) { return x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); }

/* Driver program to test above functions */ int main() { int x = 15; int y = 6;

printf("Minimum of %d and %d is ", x, y); printf("%d", min(x, y)); printf("\nMaximum of %d and %d is ", x, y); printf("%d", max(x, y)); getchar(); }

Note that the 1989 ANSI C specification doesn't specify the result of signed right-shift, so above method is not portable. If exceptions are thrown on overflows, then the values of x and y should be unsigned or cast to unsigned for the subtractions to avoid unnecessarily throwing an exception, however the right-shift needs a signed operand to produce all one bits when negative, so cast to signed there. Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax

Level Order Tree Traversal


November 7, 2009

Level order traversal of a tree is breadth first traversal for the tree.

Example Tree

Level order traversal of the above tree is 1 2 3 4 5 METHOD 1 (Use function to print a given level) Algorithm: There are basically two functions in this method. One is to print all nodes at a given level (printGivenLevel), and other is to print level order traversal of the tree (printLevelorder). printLevelorder makes

use of printGivenLevel to print nodes at all levels one by one starting from root.

/*Function to print level order traversal of tree*/ printLevelorder(tree) for d = 1 to height(tree) printGivenLevel(tree, d); /*Function to print all nodes at a given level*/ printGivenLevel(tree, level) if tree is NULL then return; if level is 1, then print(tree->data); else if level greater than 1, then printGivenLevel(tree->left, level-1); printGivenLevel(tree->right, level-1);
Implementation:
#include <stdio.h> #include <stdlib.h>

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; };

/*Function protoypes*/ void printGivenLevel(struct node* root, int level);

int height(struct node* node); struct node* newNode(int data);

/* Function to print level order traversal a tree*/ void printLevelOrder(struct node* root) { int h = height(root); int i; for(i=1; i<=h; i++) printGivenLevel(root, i); }

/* Print nodes at a given level */ void printGivenLevel(struct node* root, int level) { if(root == NULL) return; if(level == 1) printf("%d ", root->data); else if (level > 1) { printGivenLevel(root->left, level-1); printGivenLevel(root->right, level-1); } }

/* Compute the "height" of a tree -- the number of nodes along the longest path from the root node down to the farthest leaf node.*/

int height(struct node* node) { if (node==NULL) return 0; else { /* compute the height of each subtree */ int lheight = height(node->left); int rheight = height(node->right);

/* use the larger one */ if (lheight > rheight) return(lheight+1); else return(rheight+1); } }

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL;

return(node); }

/* Driver program to test above functions*/ int main() { struct node *root = newNode(1); root->left root->right root->left->left = newNode(2); = newNode(3); = newNode(4);

root->left->right = newNode(5);

printf("Level Order traversal of binary tree is \n"); printLevelOrder(root);

getchar(); return 0; }

Time Complexity: O(n^2) in worst case. For a skewed tree, printGivenLevel() takes O(n) time where n is the number of nodes in the skewed tree. So time complexity of printLevelOrder() is O(n) + O(n-1) + O(n-2) + .. + O(1) which is O(n^2).

METHOD 2 (Use Queue) Algorithm: For each node, first the node is visited and then its child nodes are put in a FIFO queue.

printLevelorder(tree)

1) Create an empty queue q 2) temp_node = root /*start from root*/ 3) Loop while temp_node is not NULL a) print temp_node->data. b) Enqueue temp_nodes children (first left then right children) to q c) Dequeue a node from q and assign its value to temp_node
Implementation: Here is a simple implementation of the above algorithm. Queue is implemented using an array with maximum size of 500. We can implement queue as linked list also.
#include <stdio.h> #include <stdlib.h> #define MAX_Q_SIZE 500

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; };

/* frunction prototypes */ struct node** createQueue(int *, int *); void enQueue(struct node **, int *, struct node *); struct node *deQueue(struct node **, int *);

/* Given a binary tree, print its nodes in level order

using array for implementing queue */ void printLevelOrder(struct node* root) { int rear, front; struct node **queue = createQueue(&front, &rear); struct node *temp_node = root;

while(temp_node) { printf("%d ", temp_node->data);

/*Enqueue left child */ if(temp_node->left) enQueue(queue, &rear, temp_node->left);

/*Enqueue right child */ if(temp_node->right) enQueue(queue, &rear, temp_node->right);

/*Dequeue node and make it temp_node*/ temp_node = deQueue(queue, &front); } }

/*UTILITY FUNCTIONS*/ struct node** createQueue(int *front, int *rear) { struct node **queue = (struct node **)malloc(sizeof(struct node*)*MAX_Q_SIZE);

*front = *rear = 0; return queue; }

void enQueue(struct node **queue, int *rear, struct node *new_node) { queue[*rear] = new_node; (*rear)++; }

struct node *deQueue(struct node **queue, int *front) { (*front)++; return queue[*front - 1]; }

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL;

return(node); }

/* Driver program to test above functions*/ int main() { struct node *root = newNode(1); root->left root->right root->left->left = newNode(2); = newNode(3); = newNode(4);

root->left->right = newNode(5);

printf("Level Order traversal of binary tree is \n"); printLevelOrder(root);

getchar(); return 0; }

Time Complexity: O(n) where n is number of nodes in the binary tree References: http://en.wikipedia.org/wiki/Breadth-first_traversal

Program to count leaf nodes in a binary tree


November 7, 2009

A node is a leaf node if both left and right child nodes of it are NULL. Here is an algorithm to get the leaf node count.

getLeafCount(node) 1) If node is NULL then return 0. 2) Else If left and right child nodes are NULL return 1. 3) Else recursively calculate leaf count of the tree using below formula.

Leaf count of a tree = Leaf count of left subtree + Leaf count of right subtree

Example Tree

Leaf count for the above tree is 3. Implementation:


#include <stdio.h> #include <stdlib.h>

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; };

/* Function to get the count of leaf nodes in a binary tree*/ unsigned int getLeafCount(struct node* node) {

if(node == NULL) return 0; if(node->left == NULL && node->right==NULL) return 1; else return getLeafCount(node->left)+ getLeafCount(node->right); }

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL;

return(node); }

/*Driver program to test above functions*/ int main() { /*create a tree*/ struct node *root = newNode(1); root->left root->right = newNode(2); = newNode(3);

root->left->left

= newNode(4);

root->left->right = newNode(5);

/*get leaf count of the above created tree*/ printf("Leaf count of the tree is %d", getLeafCount(root));

getchar(); return 0; }

Time & Space Complexities: Since this program is similar to traversal of tree, time and space complexities will be same as Tree traversal (Please see our Tree Traversal post for details)

Program for array rotation


November 10, 2009

Write a function rotate(ar[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

METHOD 1 (Use temp array)

Input arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2, n =7 1) Store d elements in a temp array temp[] = [1, 2] 2) Shift rest of the arr[] arr[] = [3, 4, 5, 6, 7, 6, 7] 3) Store back the d elements

arr[] = [3, 4, 5, 6, 7, 1, 2]
Time complexity O(n) Auxiliary Space: O(d)

METHOD 2 (Rotate one by one)

leftRotate(arr[], d, n) start For i = 0 to i < d Left rotate all elements of arr[] by one end
To rotate by one, store arr[0] in a temporary variable temp, move arr[1] to arr[0], arr[2] to arr[1] and finally temp to arr[n-1] Let us take the same example arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2 Rotate arr[] by one 2 times We get [2, 3, 4, 5, 6, 7, 1] after first rotation and [ 3, 4, 5, 6, 7, 1, 2] after second rotation.
/*Function to left Rotate arr[] of size n by 1*/ void leftRotatebyOne(int arr[], int n);

/*Function to left rotate arr[] of size n by d*/ void leftRotate(int arr[], int d, int n) { int i; for (i = 0; i < d; i++) leftRotatebyOne(arr, n); }

void leftRotatebyOne(int arr[], int n) {

int i, temp; temp = arr[0]; for (i = 0; i < n-1; i++) arr[i] = arr[i+1]; arr[i] = temp; }

/* utility function to print an array */ void printArray(int arr[], int size) { int i; for(i = 0; i < size; i++) printf("%d ", arr[i]); }

/* Driver program to test above functions */ int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7}; leftRotate(arr, 2, 7); printArray(arr, 7); getchar(); return 0; }

Time complexity: O(n*d) Auxiliary Space: O(1)

METHOD 3 (A Juggling Algorithm) This is an extension of method 2. Instead of moving one by one,

divide the array in different sets where number of sets is equal to GCD of n and d and move the elements within sets. If GCD is 1 as is for the above example array (n = 7 and d =2), then elements will be moved within one set only, we just start with temp = arr[0] and keep moving arr[I+d] to arr[I] and finally store temp at the right place. Here is an example for n =12 and d = 3. GCD is 3 and

Let arr[] be {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} a) Elements are first moved in first set (See below diagram for this movement)

arr[] after this step --> {4 2 3 7 5 6 10 8 9 1 11 12} b) Then in second set. arr[] after this step --> {4 5 3 7 8 6 10 11 9 1 2 12} c) Finally in third set. arr[] after this step --> {4 5 6 7 8 9 10 11 12 1 2 3}
/* function to print an array */ void printArray(int arr[], int size);

/*Fuction to get gcd of a and b*/

int gcd(int a,int b);

/*Function to left rotate arr[] of siz n by d*/ void leftRotate(int arr[], int d, int n) { int i, j, k, temp; for (i = 0; i < gcd(d, n); i++) { /* move i-th values of blocks */ temp = arr[i]; j = i; while(1) { k = j + d; if (k >= n) k = k - n; if (k == i) break; arr[j] = arr[k]; j = k; } arr[j] = temp; } }

/*UTILITY FUNCTIONS*/ /* function to print an array */ void printArray(int arr[], int size) { int i;

for(i = 0; i < size; i++) printf("%d ", arr[i]); }

/*Fuction to get gcd of a and b*/ int gcd(int a,int b) { if(b==0) return a; else return gcd(b, a%b); }

/* Driver program to test above functions */ int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7}; leftRotate(arr, 2, 7); printArray(arr, 7); getchar(); return 0; }

Time complexity: O(n) Auxiliary Space: O(1) Please see following posts for other methods of array rotation: Block swap algorithm for array rotation Reversal algorithm for array rotation References: http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf

Reversal algorithm for array rotation


November 10, 2009

Write a function rotate(arr[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

Method 4(The Reversal Algorithm) Please read this for first three methods of array rotation. Algorithm:

rotate(arr[], d, reverse(arr[], reverse(arr[], reverse(arr[],

n) 1, d) ; d + 1, n); l, n);

Let AB are the two parts of the input array where A = arr[0..d-1] and B = arr[d..n-1]. The idea of the algorithm is: Reverse A to get ArB. /* Ar is reverse of A */ Reverse B to get ArBr. /* Br is reverse of B */ Reverse all to get (ArBr) r = BA. For arr[] = [1, 2, 3, 4, 5, 6, 7], d =2 and n = 7 A = [1, 2] and B = [3, 4, 5, 6, 7] Reverse A, we get ArB = [2, 1, 3, 4, 5, 6, 7] Reverse B, we get ArBr = [2, 1, 7, 6, 5, 4, 3] Reverse all, we get (ArBr)r = [3, 4, 5, 6, 7, 1, 2] Implementation:

/*Utility function to print an array */ void printArray(int arr[], int size);

/* Utility function to reverse arr[] from start to end */ void rvereseArray(int arr[], int start, int end);

/* Function to left rotate arr[] of size n by d */ void leftRotate(int arr[], int d, int n) { rvereseArray(arr, 0, d-1); rvereseArray(arr, d, n-1); rvereseArray(arr, 0, n-1); }

/*UTILITY FUNCTIONS*/ /* function to print an array */ void printArray(int arr[], int size) { int i; for(i = 0; i < size; i++) printf("%d ", arr[i]); printf("%\n "); }

/*Function to reverse arr[] from index start to end*/ void rvereseArray(int arr[], int start, int end) { int i; int temp;

while(start < end) { temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; } }

/* Driver program to test above functions */ int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7}; leftRotate(arr, 2, 7); printArray(arr, 7); getchar(); return 0; }

Time Complexity: O(n) References: http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf

Block swap algorithm for array rotation


November 14, 2009

Write a function rotate(ar[], d, n) that rotates arr[] of size n by d elements.

Rotation of the above array by 2 will make array

Algorithm:

Initialize A = arr[0..d-1] and B = arr[d..n-1] 1) Do following until size of A is equal to size of B a) If A is shorter, divide B into Bl and Br such that Br is of same length as A. Swap A and Br to change ABlBr into BrBlA. Now A is at its final place, so recur on pieces of B. b) If A is longer, divide A into Al and Ar such that Al is of same length as B Swap Al and B to change AlArB into BArAl. Now B is at its final place, so recur on pieces of A. 2) Finally when A and B are of equal size, block swap them.
Recursive Implementation:
#include<stdio.h>

/*Prototype for utility functions */ void printArray(int arr[], int size); void swap(int arr[], int fi, int si, int d);

void leftRotate(int arr[], int d, int n)

{ /* Return If number of elements to be rotated is zero or equal to array size */ if(d == 0 || d == n) return;

/*If number of elements to be rotated is exactly half of array size */ if(n-d == d) { swap(arr, 0, n-d, d); return; }

/* If A is shorter*/ if(d < n-d) { swap(arr, 0, n-d, d); leftRotate(arr, d, n-d); } else /* If B is shorter*/ { swap(arr, 0, d, n-d); leftRotate(arr+n-d, 2*d-n, d); /*This is tricky*/ } }

/*UTILITY FUNCTIONS*/ /* function to print an array */

void printArray(int arr[], int size) { int i; for(i = 0; i < size; i++) printf("%d ", arr[i]); printf("%\n "); }

/*This function swaps d elements starting at index fi with d elements starting at index si */ void swap(int arr[], int fi, int si, int d) { int i, temp; for(i = 0; i<d; i++) { temp = arr[fi + i]; arr[fi + i] = arr[si + i]; arr[si + i] = temp; } }

/* Driver program to test above functions */ int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7}; leftRotate(arr, 2, 7); printArray(arr, 7); getchar(); return 0; }

Iterative Implementation: Here is iterative implementation of the same algorithm. Same utility function swap() is used here.
void leftRotate(int arr[], int d, int n) { int i, j; if(d == 0 || d == n) return; i = d; j = n - d; while (i != j) { if(i < j) /*A is shorter*/ { swap(arr, d-i, d+j-i, i); j -= i; } else /*B is shorter*/ { swap(arr, d-i, d, j); i -= j; } // printArray(arr, 7); } /*Finally, block swap A and B*/ swap(arr, d-i, d, i); }

Time Complexity: O(n)

Please see following posts for other methods of array rotation: http://geeksforgeeks.org/?p=2398 http://geeksforgeeks.org/?p=2838 References: http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf

Data Structures and Algorithms | Set 3


November 15, 2009

Following questions have asked in GATE CS exam. 1. Suppose you are given an array s[1...n] and a procedure reverse (s,i,j) which reverses the order of elements in a between positions i and j (both inclusive). What does the following sequence

do, where reverse reverse reverse

1 < (s, (s, (s,

k <= n: 1, k); k + 1, n); 1, n);

(GATE CS 2000) (a) Rotates s left by k positions (b) Leaves s unchanged (c) Reverses all elements of s (d) None of the above Answer: (a) Effect of the above 3 reversals for any k is equivalent to left rotation of the array of size n by k. Please see this post for details. If we rotate an array n times for k = 1 to n, we get the same array back.

2. The best data structure to check whether an arithmetic expression has balanced parentheses is a (GATE CS 2004) a) queue b) stack

c) tree d) list Answer(b) There are three types of parentheses [ ] { } (). Below is an arbit c code segment which has parentheses of all three types.
void func(int c, int a[]) { return ((c +2) } + arr[(c-2)]) ;

Stack is a straightforward choice for checking if left and right parentheses are balanced. Here is a algorithm to do the same.
/*Return 1 if expression has balanced parentheses */ bool areParenthesesBalanced(expression ) { for each character in expression { if(character == ( || character == { || character == [) push(stack, character); if(character == ) || character == } || character == ]) { if(isEmpty(stack)) return 0; /*We are seeing a right parenthesis without a left pair*/

/* Pop the top element from stack, if it is not a pair bracket of character then there is a mismatch. This will happen for expressions like {(}) */ else if (! isMatchingPair(pop(stack), character) ) return 0;

} }

if(isEmpty(stack)) return 1; /*balanced*/ else return 0; /*not balanced*/

} /* End of function to check parentheses */

/* Returns 1 if character1 and character2 are matching left and right parentheses */ bool isMatchingPair(character1, character2) { if(character1 == ( && character2 == )) return 1; else If(character1 == { && character2 == }) return 1; else If(character1 == [ && character2 == ]) return 1; else return 0; }

3. Level order traversal of a rooted tree can be done by starting from the root and performing (GATE CS 2004) a) preorder traversal b) in-order traversal c) depth first search d) breadth first search

Answer(d) See this post for details

4. Given the following input (4322, 1334, 1471, 9679, 1989, 6171, 6173, 4199) and the hash function x mod 10, which of the following statements are true? i. 9679, 1989, 4199 hash to the same value ii. 1471, 6171 has to the same value iii. All elements hash to the same value iv. Each element hashes to a different value (GATE CS 2004) a) i only b) ii only c) i and ii only d) iii or iv Answer (c) 5. Postorder traversal of a given binary search tree, T produces the following sequence of keys 10, 9, 23, 22, 27, 25, 15, 50, 95, 60, 40, 29 Which one of the following sequences of keys can be the result of an in-order traversal of the tree T? (GATE CS 2005) a) 9, 10, 15, 22, 23, 25, 27, 29, 40, 50, 60, 95 b) 9, 10, 15, 22, 40, 50, 60, 95, 23, 25, 27, 29 c) 29, 15, 9, 10, 25, 22, 23, 27, 40, 60, 50, 95 d) 95, 50, 60, 40, 27, 23, 22, 25, 10, 9, 15, 29 Answer (a) Inorder traversal of a BST always gives elements in increasing order. Among all four options, a) is the only increasing order sequence.

Output of C programs | Set 8


November 18, 2009

Predict the output of below C programs. Question 1:

#include<stdio.h> int main() { int x = 5, p = 10; printf("%*d", x, p);

getchar(); return 0; }

Output: 10 Explanation: Please see standard printf function definition

int printf ( const char * format, ... );


format: String that contains the text to be written to stdout. It can optionally contain embedded format tags that are substituted by the values specified in subsequent argument(s) and formatted as requested. The number of arguments following the format parameters should at least be as much as the number of format tags. The format tags follow this prototype:

%[flags][width][.precision][length]specifier
You can see details of all above parts here http://www.cplusplus.com/reference/clibrary/cstdio/printf/. The main thing to note is below the line about precision * (star): The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted. So, in the above example 5 is precision and 10 is the actual value to be printed. (Thanks to Ajay Mishra for providing the solution)

Question 2
int main() { char arr[] char *ptr = "geeksforgeeks"; = arr;

while(*ptr != '\0') ++*ptr++; printf("%s %s", arr, ptr);

getchar(); return 0; }

Output: hffltgpshfflt Explanation: The crust of this question lies in expression ++*ptr++. If one knows the precedence and associativity of the operators then there is nothing much left. Below is the precedence of operators.

Postfixx ++ Prefix ++ Dereference *

left-to-right right-to-left right-to-left

Therefore the expression ++*ptr++ has following effect Value of *ptr is incremented Value of ptr is incremented

Question 3

int main() { signed char i=0; for(; i >= 0; i++); printf("%d\n", i);

getchar(); return 0; }

Output: -128 Explanation: Here, the first thing to be noticed is the semi-colon in the end of for loop. So basically, theres no body for the for loop. And printf will print the value of i when control comes out of the for loop. Also, notice that the first statement i.e. initializer in the for loop is not present. But i has been initialized at the declaration time. Since i is a signed character, it can take value from -128 to 127. So in the for loop, i will keep incrementing and the condition is met till roll over happens. At the roll over, i will become -128 after 127, in that case condition is not met and control comes out of the for loop.

Question 4
#include <stdio.h> void fun(const char **p) { } int main(int argc, char **argv) { fun(argv); getchar(); return 0;

Output: Compiler error. Explanation: Parameter passed to fun() and parameter expected in definition are of incompatible types. fun() expects const char** while passed parameter is of type char **. Now try following program, it will work.

void fun(const char **p) { } int main(int argc, char **argv) { const char **temp; fun(temp); getchar(); return 0; } A program to check if a binary tree is BST or not
November 21, 2009

A binary search tree (BST) is a node based binary tree data structure which has the following properties. The left subtree of a node contains only nodes with keys less than the nodes key. The right subtree of a node contains only nodes with keys greater than the nodes key. Both the left and right subtrees must also be binary search trees. From the above properties it naturally follows that: Each node (item in the tree) has a distinct key.

METHOD 1 (Simple but Wrong) Following is a simple program. For each node, check if left node of it is smaller than the node and right node of it is greater than the node.
int isBST(struct node* node) { if (node == NULL) return 1;

/* false if left is > than node */ if (node->left != NULL && node->left->data > node->data) return 0;

/* false if right is < than node */ if (node->right != NULL && node->right->data < node->data) return 0;

/* false if, recursively, the left or right is not a BST */ if (!isBST(node->left) || !isBST(node->right)) return 0;

/* passing all that, it's a BST */ return 1; }

This approach is wrong as this will return true for below binary tree (and below tree is not a BST because 4 is in left subtree of 3)

METHOD 2 (Correct but not efficient) For each node, check if max value in left subtree is smaller than the node and min value in right subtree greater than the node.
/* Returns true if a binary tree is a binary search tree */ int isBST(struct node* node) { if (node == NULL) return(true);

/* false if the max of the left is > than us */ if (node->left!=NULL && maxValue(node->left) > node->data) return(false);

/* false if the min of the right is <= than us */ if (node->right!=NULL && minValue(node->right) < node->data) return(false);

/* false if, recursively, the left or right is not a BST */ if (!isBST(node->left) || !isBST(node->right)) return(false);

/* passing all that, it's a BST */ return(true); }

It is assumed that you have helper functions minValue() and maxValue() that return the min or max int value from a non-empty tree

METHOD 3 (Correct and Efficient) Method 2 above runs slowly since it traverses over some parts of the tree many times. A better solution looks at each node only once. The trick is to write a utility helper function isBSTUtil(struct node* node, int min, int max) that traverses down the tree keeping track of the narrowing min and max allowed values as it goes, looking at each node only once. The initial values for min and max should be INT_MIN and INT_MAX they narrow from there.

/* Returns true if the given tree is a binary search tree (efficient version). */ int isBST(struct node* node) { return(isBSTUtil(node, INT_MIN, INT_MAX)); } /* Returns true if the given tree is a BST and its values are >= min and <= max. */ int isBSTUtil(struct node* node, int min, int max)
Implementation:
#include <stdio.h> #include <stdlib.h>

#include <limits.h>

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; };

int isBSTUtil(struct node* node, int min, int max);

/* Returns true if the given tree is a binary search tree (efficient version). */ int isBST(struct node* node) { return(isBSTUtil(node, INT_MIN, INT_MAX)); }

/* Returns true if the given tree is a BST and its values are >= min and <= max. */ int isBSTUtil(struct node* node, int min, int max) {

/* an empty tree is BST */ if (node==NULL) return 1;

/* false if this node violates the min/max constraint */ if (node->data < min || node->data > max) return 0;

/* otherwise check the subtrees recursively, tightening the min or max constraint */ return isBSTUtil(node->left, min, node->data-1) && values isBSTUtil(node->right, node->data+1, max); values } // Allow only distinct

// Allow only distinct

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL;

return(node); }

/* Driver program to test above functions*/ int main() { struct node *root = newNode(4);

root->left root->right root->left->left

= newNode(2); = newNode(5); = newNode(1);

root->left->right = newNode(3);

if(isBST(root)) printf("Is BST"); else printf("Not a BST");

getchar(); return 0; }

Time Complexity: O(n) Auxiliary Space : O(1) if Function Call Stack size is not considered, otherwise O(n) METHOD 4(Using In-Order Traversal) Thanks to LJW489 for suggesting this method. 1) Do In-Order Traversal of the given tree and store the result in a temp array. 3) Check if the temp array is sorted in ascending order, if it is, then the tree is BST. Time Complexity: O(n) We can avoid the use of Auxiliary Array. While doing In-Order traversal, we can keep track of previously visited node. If the value of the currently visited node is less than the previous value, then tree is not BST. Thanks to ygos for this space optimization.
bool isBST(struct node* root) { static struct node *prev = NULL;

// traverse the tree in inorder fashion and keep track of prev node if (root) { if (!isBST(root->left)) return false;

// Allows only distinct valued nodes if (prev != NULL && root->data <= prev->data) return false;

prev = root;

return isBST(root->right); }

return true; }

The use of static variable can also be avoided by using reference to prev node as a parameter (Similar to this post). Sources: http://en.wikipedia.org/wiki/Binary_search_tree http://cslibrary.stanford.edu/110/BinaryTrees.html

Compute modulus division by a power-of-2-number


November 22, 2009

Compute n modulo d without division(/) and modulo(%) operators, where d is a power of 2 number. Let ith bit from right is set in d. For getting n modulus d, we just need to return 0 to i-1 (from right) bits of n as they are and other bits as 0.

For example if n = 6 (00..110) and d = 4(00..100). Last set bit in d is at position 3 (from right side). So we need to return last two bits of n as they are and other bits as 0, i.e., 00..010. Now doing it is so easy, guess it. Yes, you have guessing it right. See the below program.
#include<stdio.h>

/* This function will return n % d. d must be one of: 1, 2, 4, 8, 16, 32, */ unsigned int getModulo(unsigned int n, unsigned int d) { return ( n & (d-1) ); }

/* Driver program to test above function */ int main() { unsigned int n = 6; unsigned int d = 4; /*d must be a power of 2*/ printf("%u moduo %u is %u", n, d, getModulo(n, d));

getchar(); return 0; }

References: http://graphics.stanford.edu/~seander/bithacks.html#ModulusDivision Easy

Maximum sum such that no two elements are adjacent


November 26, 2009

Question: Given an array of positive numbers, find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be adjacent in the array. So 3 2 7 10 should return 13 (sum of 3 and 10) or 3 2 5 10 7 should return 15 (sum of 3, 5 and 7).Answer the question in most efficient way. Algorithm: Loop for all elements in arr[] and maintain two sums incl and excl where incl = Max sum including the previous element and excl = Max sum excluding the previous element. Max sum excluding the current element will be max(incl, excl) and max sum including the current element will be excl + current element (Note that only excl is considered because elements cannot be adjacent). At the end of the loop return max of incl and excl. Example:

arr[] = {5, inc = 5 exc = 0

5, 10, 40, 50, 35}

For i = 1 (current element is 5) incl = (excl + arr[i]) = 5 excl = max(5, 0) = 5 For i = 2 (current element is 10) incl = (excl + arr[i]) = 15 excl = max(5, 5) = 5 For i = 3 (current element is 40) incl = (excl + arr[i]) = 45 excl = max(5, 15) = 15 For i = 4 (current element is 50) incl = (excl + arr[i]) = 65

excl =

max(45, 15) = 45

For i = 5 (current element is 35) incl = (excl + arr[i]) = 80 excl = max(5, 15) = 65 And 35 is the last element. So, answer is max(incl, excl) = 80
Thanks to Debanjan for providing code. Implementation:
#include<stdio.h>

/*Function to return max sum such that no two elements are adjacent */ int FindMaxSum(int arr[], int n) { int incl = arr[0]; int excl = 0; int excl_new; int i;

for (i = 1; i < n; i++) { /* current max excluding i */ excl_new = (incl > excl)? incl: excl;

/* current max including i */ incl = excl + arr[i]; excl = excl_new; }

/* return max of incl and excl */ return ((incl > excl)? incl : excl); }

/* Driver program to test above function */ int main() { int arr[] = {5, 5, 10, 100, 10, 5}; printf("%d \n", FindMaxSum(arr, 6)); getchar(); return 0; }

Time Complexity: O(n) Now try the same problem for array with negative numbers also.

Data Structures and Algorithms | Set 4


November 30, 2009

Following questions have been asked in GATE CS exam. 1. Consider the following C program segment
struct CellNode { struct CelINode *leftchild; int element; struct CelINode *rightChild; }

int Dosomething(struct CelINode *ptr)

{ int value = 0; if (ptr != NULL) { if (ptr->leftChild != NULL) value = 1 + DoSomething(ptr->leftChild); if (ptr->rightChild != NULL) value = max(value, 1 + DoSomething(ptr->rightChild)); } return (value); }

The value returned by the function DoSomething when a pointer to the root of a non-empty tree is passed as argument is (GATE CS 2004) a) The number of leaf nodes in the tree b) The number of nodes in the tree c) The number of internal nodes in the tree d) The height of the tree Answer: (d) Explanation: DoSomething() returns max(height of left child + 1, height of left child + 1). So given that pointer to root of tree is passed to DoSomething(), it will return height of the tree. Note that this implementation follows the convention where height of a single node is 0. 2. Suppose we run Dijkstras single source shortest-path algorithm on the following edge weighted directed graph with vertex P as the source. In what order do the nodes get included into the set of vertices for which the shortest path distances are finalized? (GATE CS 2004) a) P, Q, R, S, T, U b) P, Q, R, U, S, T

c) P, Q, R, U, T, S d) P, Q, T, R, U, S

Answer (b) 3. Suppose each set is represented as a linked list with elements in arbitrary order. Which of the operations among union, intersection, membership, cardinality will be the slowest? (GATE CS 2004) a) union only b) intersection, membership c) membership, cardinality d) union, intersection Answer (a) Cardinality and membership are definably not the slowest one. For cardinality, just count the number of nodes in a list. For membership, just traverse the list and look for a match For getting intersection of L1 and L2, search for each element of L1 in L2 and print the elements we find in L2. There can be many ways for getting union of L1 and L2. One of them is as follows a) Print all the nodes of L1 and print only those which are not present in L2. b) Print nodes of L2. All of these methods will require more operations than intersection as we have to process intersection node plus other nodes. 4. The time complexity of the following C function is (assume n > 0 (GATE CS 2004)

int recursive (mt n) { if (n == 1) return (1); else return (recursive (n-1) + recursive (n-1)); }

a) 0(n) b) 0(nlogn) c) 0(n^2) d) 0(2^n) Answer(d) Explanation: Recursive expression for the above program will be.

T(n) = 2T(n-1) + c T(1) = c1.


Let us solve it.

T(n) = 2(2T(n-2) + c) + c 3c T(n) = 8T(n-3) + 6c + c 7c T(n) = 16T(n-4) + 14c + c + 15c

= 4T(n-2) + = = 8T(n-3) + 16T(n-4)

............................................... ............. ............................................... .............. T(n) = (2^(n-1))T(1) + (2^(n-1) - 1)c T(n) = O(2^n)

C Language | Set 3
December 4, 2009

Following questions have been asked in GATE CS exam. 1.Assume the following C variable declaration

int *A [10], B[10][10];


Of the following expressions I A[2] II A[2][3] III B[1] IV B[2][3] which will not give compile-time errors if used as left hand sides of assignment statements in a C program (GATE CS 2003)? a) I, II, and IV only b) II, III, and IV only c) II and IV only d) IV only Answer (a) See below program
int main() { int *A[10], B[10][10]; int C[] = {12, 11, 13, 14};

/* No problem with below statement as A[2] is a pointer and we are assigning a value to pointer */ A[2] = C;

/* No problem with below statement also as array style indexing can be done with pointers*/

A[2][3] = 15;

/* Simple assignment to an element of a 2D array*/ B[2][3] = 15;

printf("%d %d", A[2][0], A[2][3]); getchar(); }

2. Consider the following declaration of a two-dimensional array in C:

char a[100][100];
Assuming that the main memory is byte-addressable and that the array is stored starting from memory address 0, the address of a[40][50] is (GATE CS 2002) a) 4040 b) 4050 c) 5040 d) 5050 Answer(b)

Address of a[40][50] = Base address + 40*100*element_size + 50*element_size 0 + 4000*1 + 50*1 4050

3. The C language is. (GATE CS 2002) a) A context free language b) A context sensitive language

c) A regular language d) Parsable fully only by a Turing machine Answer (a) Most programming languages including C, C++, Java and Pascal can be approximated by context-free grammar and compilers for them have been developed based on properties of context-free languages. References: http://acm.pku.edu.cn/JudgeOnline/problem?id=3220 http://www.cs.odu.edu/~toida/nerzic/390teched/cfl/cfg.html

4 The most appropriate matching for the following pairs (GATE CS 2000)

X: m=malloc(5); m= NULL; dangling pointers Y: free(n); n->value=5; uninitialized pointers Z: char *p; *p = a; is:
(a) X1 Y3 Z-2 (b) X2 Y1 Z-3 (C) X3 Y2 Z-1 (d) X3 Y1 Z-2

1: using 2: using 3. lost memory

Answer (d) X -> A pointer is assigned to NULL without freeing memory so a clear example of memory leak Y -> Trying to retrieve value after freeing it so dangling pointer. Z -> Using uninitialized pointers

5. Consider the following C-program:

void foo(int n, int sum) { int k = 0, j = 0; if (n == 0) return; k = n % 10; j = n / 10; sum = sum + k; foo (j, sum); printf ("%d,", k); }

int main () { int a = 2048, sum = 0; foo (a, sum); printf ("%d\n", sum);

getchar(); }

What does the above program print? (GATE CS 2005) (a) 8, 4, 0, 2, 14 (b) 8, 4, 0, 2, 0 (C) 2, 0, 4, 8, 14 (d) 2, 0, 4, 8, 0 Answer (d) sum has no use in foo(), it is there just to confuse. Function foo() just prints all digits of a number. In main, there is one more printf statement after foo(), so one more 0 is printed after all digits of n.

Data Structures and Algorithms | Set 5


December 6, 2009

Following questions have been asked in GATE CS exam. 1. Consider the following C function. float f(float x, int y) { float p, s; int i; for (s=1, p=1, i=1; i < y; i ++) { p*= x/i; s+=p; } return s; }

For large values of y, the return value of the function f best approximates (GATE CS 2003) a) x^y b) e^x c) ln(1 + x) d) x^x Answer (b) The function f() is implementation of Taylors Series to calculates e^x

e^x = 1 + x + x^2/2! + x^3/3! + --More is the value of y more precise value of e^x will be returned by f() References: http://en.wikipedia.org/wiki/E_%28mathematical_constant%29 2. In the worst case, the number of comparisons needed to search a singly linked list of length n for a given element is (GATE CS 2002) a) log 2 n b) n/2 c) log 2 n 1 d) n Answer(d) In the worst case, the element to be searched has to be compared with all elements of linked list.

3. The elements 32, 15, 20, 30, 12, 25, 16 are inserted one by one in the given order into a Max Heap. The resultant Max Heap is.

Answer (a) 4. Consider the following three claims I (n + k)^m = (n^m), where k and m are constants II 2^(n + 1) = 0(2^n) III 2^(2n + 1) = 0(2^n) Which of these claims are correct? (GATE CS 2003) (a) I and II (b) I and III (c) II and III (d) I, II and III Answer(a)

(I) (n+m)^k = n^k + c1*n^(k-1) + ... k^m = (n^k) (II) 2^(n+1) = 2*2^n = O(2^n)
5. A single array A[1..MAXSIZE] is used to implement two stacks. The two stacks grow from opposite ends of the array. Variables top1 and top2 (topl< top 2) point to the location of the topmost element in each of the stacks. If the space is to be used efficiently, the condition for

stack full is (GATE CS 2004) a) (top1 = MAXSIZE/2) and (top2 = MAXSIZE/2+1) b) top1 + top2 = MAXSIZE c) (top1= MAXSIZE/2) or (top2 = MAXSIZE) d) top1= top2 -1 Answer(d) If we are to use space efficiently then size of the any stack can be more than MAXSIZE/2. Both stacks will grow from both ends and if any of the stack top reaches near to the other top then stacks are full. So the condition will be top1 = top2 -1 (given that top1 < top2)

Output of C Programs | Set 9


December 6, 2009

Predict the output of the below programs. Question 1


int main() { int c=5; printf("%d\n%d\n%d", c, c <<= 2, c >>= 2); getchar(); }

Output: Compiler dependent Evaluation order of parameters is not defined by C standard and is dependent on compiler implementation. It is never safe to depend on the order of parameter evaluation. For example, a function call like above may very well behave differently from one compiler to another. References: http://gcc.gnu.org/onlinedocs/gcc/Non_002dbugs.html

Question 2
int main() {

char arr[] = {1, 2, 3}; char *p = arr; if(&p == &arr) printf("Same"); else printf("Not same"); getchar(); }

Output: Not Same &arr is an alias for &arr[0] and returns the address of the first element in array, but &p returns the address of pointer p. Now try below program
int main() { char arr[] = {1, 2, 3}; char *p = arr; if(p == &arr) printf("Same"); else printf("Not same"); getchar(); }

Question 3
int main() { char arr[] = {1, 2, 3}; char *p = arr;

printf(" %d ", sizeof(p)); printf(" %d ", sizeof(arr)); getchar(); }

Output 4 3 sizeof(arr) returns the amount of memory used by all elements in array and sizeof(p) returns the amount of memory used by the pointer variable itself.

Question 4
int x = 0; int f() { return x; }

int g() { int x = 1; return f(); }

int main() { printf("%d", g()); printf("\n"); getchar(); }

Output: 0 In C, variables are always statically (or lexically) scoped. Binding of x inside f() to global variable x is defined at compile time and not dependent on who is calling it. Hence, output for the above program will be 0. On a side note, Perl supports both dynamic ans static scoping. Perls keyword my defines a statically scoped local variable, while the keyword local defines dynamically scoped local variable. So in Perl, similar (see below) program will print 1.
$x = 0; sub f { return $x; } sub g { local $x = 1; return f(); } print g()."\n";

Reference: http://en.wikipedia.org/wiki/Scope_%28programming%29

Leaders in an array
December 7, 2009

Write a program to print all the LEADERS in the array. An element is leader if it is greater than all the elements to its right side. And the rightmost element is always a leader. For example int the array {16, 17, 4, 3, 5, 2}, leaders are 17, 5 and 2. Let the input array be arr[] and size of the array be size. Method 1 (Simple) Use two loops. The outer loop runs from 0 to size 1 and one by one

picks all elements from left to right. The inner loop compares the picked element to all the elements to its right side. If the picked element is greater than all the elements to its right side, then the picked element is the leader.
/*Function to print leaders in an array */ void printLeaders(int arr[], int size) { int i, j;

for (i = 0; i < size; i++) { for (j = i+1; j < size; j++) { if(arr[i] <= arr[j]) break; } if(j == size) // the loop didn't break { printf("%d ", arr[i]); } } }

/*Driver program to test above function*/ int main() { int arr[] = {16, 17, 4, 3, 5, 2}; printLeaders(arr, 6); getchar(); }

// Output:

17 5 2

Time Complexity: O(n*n)

Method 2 (Scan from right) Scan all the elements from right to left in array and keep track of maximum till now. When maximum changes its value, print it.
/*Function to print leaders in an array */ void printLeaders(int arr[], int size) { int max_from_right = int i; arr[size-1];

/* Rightmost element is always leader */ printf("%d ", max_from_right);

for(i = size-2; i >= 0; i--) { if(max_from_right < arr[i]) { printf("%d ", arr[i]); max_from_right = arr[i]; } } }

/*Driver program to test above function*/ int main() {

int arr[] = {16, 17, 4, 3, 5, 2}; printLeaders(arr, 6); getchar(); } // Output: 2 5 17

Time Complexity: O(n)

Data Structures and Algorithms | Set 6


December 9, 2009

Following questions have been asked in GATE CS exam. 1. The usual (n^2) implementation of Insertion Sort to sort an array uses linear search to identify the position where an element is to be inserted into the already sorted part of the array. If, instead, we use binary search to identify the position, the worst case running time will (GATE CS 2003) (a) remain (n^2) (b) become (n(log n)^2) (c) become (n log n) (d) become (n) Answer (a) If we use binary search then there will be comparisons in the worst case, which is (n log n) ( If you want to know how can be equal to (n log n), then see this for proof). But the algorithm as a whole will still have a running time of (n^2) on average because of the series of swaps required for each insertion. Reference: http://en.wikipedia.org/wiki/Insertion_sort

2. The tightest lower bound on the number of comparisons, in the worst case, for comparison-based sorting is of the order of a) n b) n^2

c) nlogn d) n(log^2)n Answer (c) The number of comparisons that a comparison sort algorithm requires increases in proportion to nlog(n), where n is the number of elements to sort. This bound is asymptotically tight: Given a list of distinct numbers (we can assume this because this is a worst-case analysis), there are n factorial permutations exactly one of which is the list in sorted order. The sort algorithm must gain enough information from the comparisons to identify the correct permutations. If the algorithm always completes after at most f(n) steps, it cannot distinguish more than 2^f(n) cases because the keys are distinct and each comparison has only two possible outcomes. Therefore, 2^f(n) n!, or equivalently f(n) [Tex]\log_2[/Tex](n!).

References: http://en.wikipedia.org/wiki/Comparison_sort http://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15451s07/www/lecture_notes/lect0130.pdf

3. The problem 3-SAT and 2-SAT are a) both in P b) both NP complete c) NP-complete and in P respectively d) undecidable and NP-complete respectively Answer (c) The Boolean satisfiability problem (SAT) is a decision problem, whose instance is a Boolean expression written using only AND, OR, NOT, variables, and parentheses. The problem is: given the expression, is there some assignment of TRUE and FALSE values to the variables that will make the entire expression true? A formula of propositional logic is said to be satisfiable if logical values can be assigned to its variables in a way that makes the formula true.

3-SAT and 2-SAT are special cases of k-satisfiability (k-SAT) or simply satisfiability (SAT), when each clause contains exactly k = 3 and k = 2 literals respectively. 2-SAT is P while 3-SAT is NP Complete. (See this for explanation) References: http://en.wikipedia.org/wiki/Boolean_satisfiability_problem

4. Consider the following graph

Among the following sequences I) a b e g h f II) a b f e h g III) a b f h g e IV) a f g h b e Which are depth first traversals of the above graph? (GATE CS 2003) a) I, II and IV only b) I and IV only c) II, III and IV only d) I, III and IV only Answer (d)

Principle of programming languages | Set 1


December 14, 2009
Following questions have been asked in GATE CS exam.

1.The most appropriate matching for the following pairs

X: Indirect addressing Y: Immediate addressing Z: Auto decrement addressing


is (GATE CS 2000) (a) X3 Y2 Z1 (b) X1 Y3 Z2 (c) X2 Y3 Z1 (d) X3 Y1 Z2 Answer (c) Reference:

1: Loops 2: Pointers 3. Constants

http://en.wikipedia.org/wiki/Addressing_mode http://www.cs.nmsu.edu/~pfeiffer/classes/273/notes/immdirext.html
2. Aliasing in the context of programming languages refers to (GATE CS 2000) (a) multiple variables having the same memory location (b) multiple variables having the same value (c) multiple variables having the same identifier (d) multiple uses of the same variable Answer (a) Aliasing describes a situation in which a data location in memory can be accessed through different symbolic names in the program. Reference

http://en.wikipedia.org/wiki/Aliasing_%28computing%29

3. What is printed by the print statements in the program P1 assuming call by reference parameter passing? (GATE CS 2001) Program Pl() { x=10; y=3; func1(y, x, x); print x; print y; }

func1 (x, y, z) { y = y + 4; z = x + y + z; }

a) 10, 3 b) 31, 3 c) 27, 7 d) None of the above Answer (b) Note the order in which parameters are passed. Inside func1(), x will actually refer to y of main(); and y and z will refer to x of main(). The Statement y = y + 4; will result in 14 and statement z = x + y + z will make z = 3 + 14 + 14 = 31 (because y and z point to same variable x of main). Since z refers to x of main(), main will print 31.

4. Consider the following program Program P2 var n: int: procedure W(var x: int) begin x=x+1; print x; end

procedure D begin var n: int; n=3; W(n); end begin //beginP2

n=10; D; end

If the language has dynamic scoping and parameters are passed by reference, what will be printed by the program? (GATE CS 2001) a) 10 b) 11 c) 3 d) None of the above Answer(d) Program will print 4. 5. The- results returned by functions under value-result and reference parameter passing conventions (GATE CS 2002) a) Do not differ b) Differ in the presence of loops c) Differ in all cases d) May differ in the presence of exceptions Answer(d) In call-by-reference evaluation, a function receives an implicit reference to the argument, rather than a copy of its value. This typically means that the function can modify the argument- something that will be seen by its caller. Note that C doesnt support call by reference but call-by-reference can be implemented using pointers. Call-by-value-result uses a combination of call-by-value and call-by-reference. Call-by-value-result works by creating local versions of the parameters passed in. However, the values in these local versions are copied back to the original arguments after the end of the procedure. In case of exceptions, results may differ. Let us see below example in an arbitrary language

int addTwo(a, b) { a = a + b; b = a + b; return b; }


If call-by-value-result is used then calling addTwo(x, x) will return 3x (see below for explanation).

a = a + b; will result in a = x + x

b = a + b; will result in

b = 2x + x

If call-by-reference is used then addTwo(x, x) will return 4x (see below for explanation).

a = a + b; will result in a = x + x b = a + b; will result in b = 2x + 2x


References:

http://c2.com/cgi/wiki?CallByValueResult http://en.wikipedia.org/wiki/Evaluation_strategy

Write a recursive function to print reverse of a Linked List


December 19, 2009

Note that the question is only about printing the reverse. To reverse the list itself see this Difficulty Level: Rookie Algorithm

printReverse(head) 1. call print reverse for hed->next 2. print head->data


Implementation:
#include<stdio.h> #include<stdlib.h>

/* Link list node */ struct node { int data; struct node* next; };

/* Function to reverse the linked list */

void printReverse(struct node* head) { // Base case if(head == NULL) return;

// print the list after head node printReverse(head->next);

// After everything else is printed, print head printf("%d } ", head->data);

/*UTILITY FUNCTIONS*/ /* Push a node to linked list. Note that this function changes the head */ void push(struct node** head_ref, char new_data) { /* allocate node */ struct node* new_node = (struct node*) malloc(sizeof(struct node));

/* put in the data new_node->data

*/

= new_data;

/* link the old list off the new node */ new_node->next = (*head_ref);

/* move the head to pochar to the new node */

(*head_ref) }

= new_node;

/* Drier program to test above function*/ int main() {

struct node* head = NULL;

push(&head, 1); push(&head, 2); push(&head, 3); push(&head, 4);

printReverse(head); getchar(); }

Time Complexity: O(n)

Babylonian method for square root


December 20, 2009

Algorithm: This method can be derived from (but predates) NewtonRaphson method.

1 Start with an arbitrary positive start value x (the closer to the root, the better). 2 Initialize y = 1. 3. Do following until desired approximation is achieved.

a) Get the next approximation for root using average of x and y b) Set y = n/x
Implementation:
/*Returns the square root of n. Note that the function */ float squareRoot(float n) { /*We are using n itself as initial approximation This can definitely be improved */ float x = n; float y = 1; float e = 0.000001; /* e decides the accuracy level*/ while(x - y > e) { x = (x + y)/2; y = n/x; } return x; }

/* Driver program to test above function*/ int main() { int n = 50; printf ("Square root of %d is %f", n, squareRoot(n)); getchar(); }

Example:

n = 4 /*n itself is used for initial approximation*/ Initialize x = 4, y = 1 Next Approximation x = (x + y)/2 (= 2.500000), y = n/x (=1.600000) Next Approximation x = 2.050000, y = 1.951220 Next Approximation x = 2.000610, y = 1.999390 Next Approximation x = 2.000000, y = 2.000000 Terminate as (x - y) > e now.
If we are sure that n is a perfect square, then we can use following method. The method can go in infinite loop for non-perfect-square numbers. For example, for 3 the below while loop will never terminate.
/*Returns the square root of n. Note that the function will not work for numbers which are not perfect squares*/ unsigned int squareRoot(int n) { int x = n; int y = 1; while(x > y) { x = (x + y)/2; y = n/x; } return x; }

/* Driver program to test above function*/ int main() {

int n = 49; printf (" root of %d is %d", n, squareRoot(n)); getchar(); }

References; http://en.wikipedia.org/wiki/Square_root http://en.wikipedia.org/wiki/Babylonian_method#Babylonian_method

Level order traversal in spiral form


December 20, 2009
Write a function to print spiral order traversal of a tree. For below tree, function should print 1, 2, 3, 4, 5, 6, 7.

Algorithm: This problem is an extension of the level

order traversal post.

To print the nodes in spiral order, nodes at different levels should be printed in alternating order. An additional Boolean variable ltr is used to change printing order of levels. If ltr is 1 then printGivenLevel() prints nodes from left to right else from right to left. Value of ltr is flipped in each iteration to change the order. Function to print level order traversal of tree

printLevelorder(tree) bool ltr = 0; for d = 1 to height(tree) printGivenLevel(tree, d, ltr); ltr ~= ltr /*flip ltr*/
Function to print all nodes at a given level

printGivenLevel(tree, level, ltr) if tree is NULL then return; if level is 1, then print(tree->data); else if level greater than 1, then if(rtl) printGivenLevel(tree->right, level-1, ltr); printGivenLevel(tree->left, level-1, ltr); else printGivenLevel(tree->left, level-1, ltr); printGivenLevel(tree->right, level-1, ltr);
Implementation: #include <stdio.h> #include <stdlib.h> #define bool int

/* A binary tree node has data, pointer to left child and a pointer to right child */ struct node { int data; struct node* left; struct node* right; };

/*Function protoypes*/ void printGivenLevel(struct node* root, int level, int ltr); int height(struct node* node);

struct node* newNode(int data);

/* Function to print spiral traversal of a tree*/ void printLevelOrder(struct node* root) { int h = height(root); int i;

/*ltr -> Left to Right. If this variable is set, then the given level is traverseed from left to right. */ bool ltr = 0; for(i=1; i<=h; i++) { printGivenLevel(root, i, ltr);

/*Revert ltr to traverse next level in oppposite order*/ ltr = ~ltr; } }

/* Print nodes at a given level */ void printGivenLevel(struct node* root, int level, int ltr) { if(root == NULL) return; if(level == 1) printf("%d ", root->data); else if (level > 1) {

if(ltr) { printGivenLevel(root->left, level-1, ltr); printGivenLevel(root->right, level-1, ltr); } else { printGivenLevel(root->right, level-1, ltr); printGivenLevel(root->left, level-1, ltr); } } }

/* Compute the "height" of a tree -- the number of nodes along the longest path from the root node down to the farthest leaf node.*/ int height(struct node* node) { if (node==NULL) return 0; else { /* compute the height of each subtree */ int lheight = height(node->left); int rheight = height(node->right);

/* use the larger one */ if (lheight > rheight) return(lheight+1); else return(rheight+1);

} }

/* Helper function that allocates a new node with the given data and NULL left and right pointers. */ struct node* newNode(int data) { struct node* node = (struct node*) malloc(sizeof(struct node)); node->data = data; node->left = NULL; node->right = NULL;

return(node); }

/* Driver program to test above functions*/ int main() { struct node *root = newNode(1); root->left root->right root->left->left = newNode(2); = newNode(3); = newNode(7);

root->left->right = newNode(6); root->right->left = newNode(5);

root->right->right = newNode(4); printf("Level Order traversal of binary tree is \n"); printLevelOrder(root);

getchar(); return 0; }

Data Structures and Algorithms | Set 7


December 25, 2009
Following questions have been asked in GATE CS 2006 exam. 1. In a binary max heap containing n numbers, the smallest element can be found in time (GATE CS 2006) (A) 0(n) (B) O(logn) (C) 0(loglogn) (D) 0(1) Answer (A) In a max heap, the smallest element is always present at a leaf node. So we need to check for all leaf nodes for the minimum value. Worst case complexity will be O(n)

12 / / 8 / \ / 2 \ 3 / 4 \ \ 7 / \ \ 5

2. A scheme for storing binary trees in an array X is as follows. Indexing of X starts at 1 instead of 0. the root is stored at X[1]. For a node stored at X[i], the left child, if any, is stored in X[2i] and the right child, if any, in X[2i+1]. To be able to store any binary tree on n vertices the minimum size of X should be. (GATE CS 2006) (A) log2n (B) n (C) 2n + 1 (D) 2^n 1 Answer (D) For a right skewed binary tree, number of nodes will be 2^n 1. For example, in below binary tree, node A will be stored at index 1, B at index 3, C at index 7 and D at index 15.

A \

\ B \ \ C \ \ D
3. Which one of the following in place sorting algorithms needs the minimum number of swaps? (GATE CS 2006) (A) Quick sort (B) Insertion sort (C) Selection sort (D) Heap sort Answer (C) For selection sort, number of swaps required is minimum (

(n) ).

4. An element in an array X is called a leader if it is greater than all elements to the right of it in X. The best algorithm to find all leaders in an array (GATE CS 2006) (A) Solves it in linear time using a left to right pass of the array (B) Solves it in linear time using a right to left pass of the array (C) Solves it using divide and conquer in time 8(nlogn) (D) Solves it in time 8(n2) Answer (B) Please see this post for explanation. 5. Consider a weighted complete graph G on the vertex set {v1,v2 ,v} such that the weight of the edge (v,,v) is 2|i-j|. The weight of a minimum spanning tree of G is: (GATE CS 2006) (A) n 1 (B) 2n 2 (C) nC2 (D) 2 Answer (B) Minimum spanning tree of such a graph is

v1 \ v2 \ v3

\ v4 . . . vn
Weight of the minimum spanning tree = 2|2 1| + 2|3 2| + 2|4 3| + 2|5 4| . + 2| n (n-1) | = 2n 2

For Versus While


December 31, 2009
Question: Is there any example for which the following two loops will not work same way? /*Program 1 --> For loop*/ for (<init-stmnt>; <boolean-expr>; <incr-stmnt>) { <body-statements> }

/*Program 2 --> While loop*/ <init-stmnt>; while (<boolean-expr>) { <body-statements> <incr-stmnt> }

Solution: If the body-statements contains continue, then the two programs will work in different ways See the below examples: Program 1 will print loop 3 times but Program 2 will go in an infinite loop. Example for program 1

int main() { int i = 0; for(i = 0; i < 3; i++) { printf("loop "); continue; } getchar(); return 0; }

Example for program 2 int main() { int i = 0; while(i < 3) { printf("loop"); /* printed infinite times */ continue; i++; /*This statement is never executed*/ } getchar(); return 0; }

Compiler Theory | Set 2


January 2, 2010

Following questions have been asked in GATE CS exam.

1. Given the following expression grammar: E -> E * F | F+E | F F -> F-F | id which of the following is true? (GATE CS 2000) (a) * has higher precedence than + (b) has higher precedence than * (c) + and have same precedence (d) + has higher precedence than * Answer(b) Precedence in a grammar is enforced by making sure that a production rule with higher precedence operator will never produce an expression with operator with lower precedence. In the given grammar - has higher precedence than *

2. Consider a program P that consists of two source modules M1 and M2 contained in two different files. If M1 contains a reference to a function defined in M2 the reference will be resolved at (GATE CS 2004) a) Edit time b) Compile time c) Link time d) Load time Answer (c) Compiler transforms source code into the target language. The target language is generally in binary form known as object code. Typically, an object file can contain three kinds of symbols: * defined symbols, which allow it to be called by other modules, * undefined symbols, which call the other modules where these symbols are defined, and * local symbols, used internally within the object file to facilitate relocation. When a program comprises multiple object files, the linker combines these files into a unified executable program, resolving the symbols as it goes along.

http://en.wikipedia.org/wiki/Compiler http://en.wikipedia.org/wiki/Linker_%28computing%29

3. Which of the following suffices to convert an arbitrary CFG to an LL(1) grammar? (GATE CS 2003) (a) Removing left recursion alone (b) Factoring the grammar alone (c) Removing left recursion and factoring the grammar (d) None of the above Answer(d) Removing left recursion and factoring the grammar do not suffice to convert an arbitrary CFG to LL(1) grammar. http://pages.cpsc.ucalgary.ca/~robin/class/411/LL1.3.html 4. Assume that the SLR parser for a grammar G has n1 states and the LALR parser for G has n2 states. The relationship between nl and n2 is (GATE CS 2003) (a) n1 is necessarily less than n2 (b) n1 is necessarily equal to n2 (c) n1 is necessarily greater than n2 (d) none of the above Answer (b) http://parasol.tamu.edu/people/rwerger/Courses/434/lec10.pdf http://dragonbook.stanford.edu/lecture-notes/Stanford-CS143/11LALR-Parsing.pdf

Data Structures and Algorithms | Set 8


January 2, 2010

Following questions have been asked in GATE CS exam.

1. Consider the following functions

Which of the following is true? (GATE CS 2000) (a) h(n) is 0(f(n)) (b) h(n) is 0(g(n)) (c) g(n) is not 0(f(n)) (d) f(n) is 0(g(n)) Answer (d) g(n) = 2^

= n^

f(n) and g(n) are of same asymptotic order and following statements are true. f(n) = O(g(n)) g(n) = O(f(n)). (a) and (b) are false because n! is of asymptotically higher order than n^ .

2. Let G be an undirected connected graph with distinct edge weight. Let emax be the edge with maximum weight and emin the edge with minimum weight. Which of the following statements is false? (GATE CS 2000) (a) Every minimum spanning tree of G must contain emin (b) If emax is in a minimum spanning tree, then its removal must disconnect G (c) No minimum spanning tree contains emax (d) G has a unique minimum spanning tree Answer (c) (a) and (b) are always true. (c) is false because (b) is true. (d) is true because all edge weights are distinct for G.

3. Let G be an undirected graph. Consider a depth-first traversal of G, and let T be the resulting depth-first search tree. Let u be a vertex in G and let v be the first new (unvisited) vertex visited after visiting u in the traversal. Which of the following statements is always true? (GATE CS 2000) (a) {u,v} must be an edge in G, and u is a descendant of v in T (b) {u,v} must be an edge in G, and v is a descendant of u in T (c) If {u,v} is not an edge in G then u is a leaf in T (d) If {u,v} is not an edge in G then u and v must have the same parent in T Answer (c)

4. Consider an undirected unweighted graph G. Let a breadthfirst traversal of G be done starting from a node r. Let d(r, u) and d(r, v) be the lengths of the shortest paths from r to u and v respectively, in G. lf u is visited before v during the breadth-first traversal, which of the following statements is correct? (GATE CS 2001) a) d(r, u) < d (r, v) b) d(r, u) > d(r, v) c) d(r, u) <= d (r, v) d) None of the above Answer (c) d(r, u) and d(r, v) will be equal when u and v are at same level, otherwise d(r, u) will be less than d(r, v)

5. How many undirected graphs (not necessarily connected) can be constructed out of a given set V= {V 1, V 2,V n} of n vertices ? (GATE CS 2001) a) n(n-l)/2 b) 2^n c) n! d) 2^(n(n-1)/2)

Answer (d) In an undirected graph, there can be maximum n(n-1)/2 edges. We can choose to have (or not have) any of the n(n-1)/2 edges. So, total number of undirected graphs with n vertices is 2^(n(n-1)/2).

Sort elements by frequency | Set 1


January 3, 2010

Asked By Binod Question: Print the elements of an array in the decreasing frequency if 2 numbers have same frequency then print the one which came 1st E.g. 2 5 2 8 5 6 8 8 output: 8 8 8 2 2 5 5 6.

METHOD 1 (Use Sorting)

1) Use a sorting algorithm to sort the elements O(nlogn) 2) Scan the sorted array and construct a 2D array of element and count O(n). 3) Sort the 2D array according to count O(nlogn).
Example:

Input 2 5 2 8 5 6 8 8 After sorting we get 2 2 5 5 6 8 8 8 Now construct the 2D array as 2, 2 5, 2 6, 1 8, 3 Sort by count

8, 2, 5, 6,

3 2 2 1

There is one issue with above approach (thanks to ankit for pointing this out). If we modify the input to 5 2 2 8 5 6 8 8, then we should get 8 8 8 5 5 2 2 6 and not 8 8 8 2 2 5 5 6 as will be the case. To handle this, we should use indexes in step 3, if two counts are same then we should first process(or print) the element with lower index. In step 1, we should store the indexes instead of elements.

Input 5

After sorting we get Element 2 2 5 5 6 8 8 8 Index 1 2 0 4 5 3 6 7 Now construct the 2D array as Index, Count 1, 2 0, 2 5, 1 3, 3 Sort by count (consider indexes in case of tie) 3, 3 0, 2 1, 2 5, 1 Print the elements using indexes in the above 2D array.

METHOD 2(Use BST and Sorting)

1. Insert elements in BST one by one and if an element is already present then increment the count of the node. Node of the Binary Search Tree (used in this approach) will be as follows.
struct tree { int element; int first_index /*To handle ties in counts*/ int count; }BST;

2.Store the first indexes and corresponding counts of BST in a 2D array. 3 Sort the 2D array according to counts (and use indexes in case of tie). Time Complexity: O(nlogn) if a Self Balancing Binary Search Tree is used.

METHOD 3(Use Hashing and Sorting) Using a hashing mechanism, we can store the elements (also first index) and their counts in a hash. Finally, sort the hash elements according to their counts.

These are just our thoughts about solving the problem and may not be the optimal way of solving. We are open for better solutions.

Related Links http://www.trunix.org/programlama/c/kandr2/krx604.html http://drhanson.s3.amazonaws.com/storage/documents/common.pdf

http://www.cc.gatech.edu/classes/semantics/misc/pp2.pdf

Count Inversions in an array


January 5, 2010

Inversion Count for an array indicates how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum. Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j Example: The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3). METHOD 1 (Simple) For each element, count number of elements which are on right side of it and are smaller than it.
int getInvCount(int arr[], int n) { int inv_count = 0; int i, j;

for(i = 0; i < n - 1; i++) for(j = i+1; j < n; j++) if(arr[i] > arr[j]) inv_count++;

return inv_count; }

/* Driver progra to test above functions */ int main(int argv, char** args) {

int arr[] = {1, 20, 6, 4, 5}; printf(" Number of inversions are %d \n", getInvCount(arr, 5)); getchar(); return 0; }

Time Complexity: O(n^2)

METHOD 2(Enhance Merge Sort) Suppose we know the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is the inversions we have to count during the merge step. Therefore, to get number of inversions, we need to add number of inversions in left subarray, right subarray and merge().

How to get number of inversions in merge()? In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] a[mid]) will be greater than a[j]

The complete picture:

Implementation:
#include <stdio.h> #include <stdlib.h>

int _mergeSort(int arr[], int temp[], int left, int right); int merge(int arr[], int temp[], int left, int mid, int right);

/* This function sorts the input array and returns the number of inversions in the array */ int mergeSort(int arr[], int array_size) { int *temp = (int *)malloc(sizeof(int)*array_size); return _mergeSort(arr, temp, 0, array_size - 1); }

/* An auxiliary recursive function that sorts the input array and returns the number of inversions in the array. */ int _mergeSort(int arr[], int temp[], int left, int right) { int mid, inv_count = 0; if (right > left) { /* Divide the array into two parts and call _mergeSortAndCountInv() for each of the parts */ mid = (right + left)/2;

/* Inversion count will be sum of inversions in left-part, right-part and number of inversions in merging */ inv_count = _mergeSort(arr, temp, left, mid);

inv_count += _mergeSort(arr, temp, mid+1, right);

/*Merge the two parts*/ inv_count += merge(arr, temp, left, mid+1, right); } return inv_count;

/* This funt merges two sorted arrays and returns inversion count in the arrays.*/ int merge(int arr[], int temp[], int left, int mid, int right) { int i, j, k; int inv_count = 0;

i = left; /* i is index for left subarray*/ j = mid; /* i is index for right subarray*/

k = left; /* i is index for resultant merged subarray*/ while ((i <= mid - 1) && (j <= right)) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++];

/*this is tricky -- see above explanation/diagram for merge()*/ inv_count = inv_count + (mid - i); } }

/* Copy the remaining elements of left subarray (if there are any) to temp*/

while (i <= mid - 1) temp[k++] = arr[i++];

/* Copy the remaining elements of right subarray (if there are any) to temp*/ while (j <= right) temp[k++] = arr[j++];

/*Copy back the merged elements to original array*/ for (i=left; i <= right; i++) arr[i] = temp[i];

return inv_count; }

/* Driver progra to test above functions */ int main(int argv, char** args) { int arr[] = {1, 20, 6, 4, 5}; printf(" Number of inversions are %d \n", mergeSort(arr, 5)); getchar(); return 0; }

Note that above code modifies (or sorts) the input array. If we want to count only inversions then we need to create a copy of original array and call mergeSort() on copy. Time Complexity: O(nlogn) Algorithmic Paradigm: Divide and Conquer

References: http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08inversions.pdf http://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/countinv.htm

Operating Systems | Set 4


January 8, 2010

Following questions have been asked in GATE CS exam. 1. Using a larger block size in a fixed block size file system leads to (GATE CS 2003) a) better disk throughput but poorer disk space utilization b) better disk throughput and better disk space utilization c) poorer disk throughput but better disk space utilization d) poorer disk throughput and poorer disk space utilization Answer (a) If block size is large then seek time is less (fewer blocks to seek) and disk performance is improved, but remember larger block size also causes waste of disk space. 2. Consider the following statements with respect to user-level threads and kernel supported threads i. context switch is faster with kernel-supported threads ii. for user-level threads, a system call can block the entire process iii. Kernel supported threads can be scheduled independently iv. User level threads are transparent to the kernel Which of the above statements are true? (GATE CS 2004) a) (ii), (iii) and (iv) only b) (ii) and (iii) only c) (i) and (iii) only d) (i) and (ii) only Answer(a)

http://en.wikipedia.org/wiki/Thread_%28computer_science%29

3. The minimum number of page frames that must be allocated to a running process in a virtual memory environment is determined by (GATE CS 2004) a) the instruction set architecture b) page size c) physical memory size d) number of processes in memory Answer (a) Each process needs minimum number of pages based on instruction set architecture. Example IBM 370: 6 pages to handle MVC (storage to storage move) instruction Instruction is 6 bytes, might span 2 pages. 2 pages to handle from. 2 pages to handle to. 4. In a system with 32 bit virtual addresses and 1 KB page size, use of one-level page tables for virtual to physical address translation is not practical because of (GATE CS 2003) a) the large amount of internal fragmentation b) the large amount of external fragmentation c) the large memory overhead in maintaining page tables d) the large computation overhead in the translation process Answer (c) Since page size is too small it will make size of page tables huge.

Size of page table = (total number of page table entries) *(size of a page table entry)
Let us see how many entries are there in page table

Number of entries in page table = (virtual address space size)/(page size) = (2^32)/(2^10)

= 2^22
Now, let us see how big each entry is. If size of physical memory is 512 MB then number of bits required to address a byte in 512 MB is 29. So, there will be (512MB)/(1KB) = (2^29)/(2^10) page frames in physical memory. To address a page frame 19 bits are required. Therefore, each entry in page table is required to have 19 bits.

Note that page table entry also holds auxiliary information about the page such as a present bit, a dirty or modified bit, address space or process ID information, amongst others. So size of page table > (total number of page table entries) *(size of a page table entry) > (2^22 *19) bytes > 9.5 MB
And this much memory is required for each process because each process maintains its own page table. Also, size of page table will be more for physical memory more than 512MB. Therefore, it is advised to use multilevel page table for such scenarios. References: http://barbara.stattenfield.org/ta/cs162/section-notes/sec8.txt http://en.wikipedia.org/wiki/Page_table

Why C treats array parameters as pointers?


January 10, 2010

In C, array parameters are treated as pointers. The following two definitions of foo() look different, but to the compiler they mean exactly the same thing. Its preferable to use whichever syntax is more accurate for readability. If the pointer coming in really is the base address of a whole array, then we should use [ ].
void foo(int arr_param[]) {

/* Silly but valid. Just changes the local pointer */ arr_param = NULL; }

void foo(int *arr_param) {

/* ditto */ arr_param = NULL; }

Array parameters treated as pointers because of efficiency. It is inefficient to copy the array data in terms of both memory and time; and most of the times, when we pass an array our intention is to just tell the array we interested in, not to create a copy of the array. Asked by Shobhit References: http://cslibrary.stanford.edu/101/EssentialC.pdf

Two elements whose sum is closest to zero


January 10, 2010

Question: An Array of integers is given, both +ve and -ve. You need to find the two elements such that their sum is closest to zero. For the below array, program should print -80 and 85.

METHOD 1 (Simple) For each element, find the sum of it with every other element in the array and compare sums. Finally, return the minimum sum.

Implementation
# include <stdio.h> # include <stdlib.h> /* for abs() */ # include <math.h> void minAbsSumPair(int arr[], int arr_size) { int inv_count = 0; int l, r, min_sum, sum, min_l, min_r;

/* Array should have at least two elements*/ if(arr_size < 2) { printf("Invalid Input"); return; }

/* Initialization of values */ min_l = 0; min_r = 1; min_sum = arr[0] + arr[1];

for(l = 0; l < arr_size - 1; l++) { for(r = l+1; r < arr_size; r++) { sum = arr[l] + arr[r]; if(abs(min_sum) > abs(sum)) { min_sum = sum;

min_l = l; min_r = r; } } }

printf(" The two elements whose sum is minimum are %d and %d", arr[min_l], arr[min_r]); }

/* Driver program to test above function */ int main() { int arr[] = {1, 60, -10, 70, -80, 85}; minAbsSumPair(arr, 6); getchar(); return 0; }

Time complexity: O(n^2)

METHOD 2 (Use Sorting) Thanks to baskin for suggesting this approach. We recommend to read this post for background of this approach. Algorithm 1) Sort all the elements of the input array. 2) Use two index variables l and r to traverse from left and right ends respectively. Initialize l as 0 and r as n-1. 3) sum = a[l] + a[r] 4) If sum is -ve, then l++ 5) If sum is +ve, then r

6) Keep track of abs min sum. 7) Repeat steps 3, 4, 5 and 6 while l < r Implementation
# include <stdio.h> # include <math.h> # include <limits.h>

void quickSort(int *, int, int);

/* Function to print pair of elements having minimum sum */ void minAbsSumPair(int arr[], int n) { // Variables to keep track of current sum and minimum sum int sum, min_sum = INT_MAX;

// left and right index variables int l = 0, r = n-1;

// variable to keep track of the left and right pair for min_sum int min_l = l, min_r = n-1;

/* Array should have at least two elements*/ if(n < 2) { printf("Invalid Input"); return; }

/* Sort the elements */

quickSort(arr, l, r);

while(l < r) { sum = arr[l] + arr[r];

/*If abs(sum) is less then update the result items*/ if(abs(sum) < abs(min_sum)) { min_sum = sum; min_l = l; min_r = r; } if(sum < 0) l++; else r--; }

printf(" The two elements whose sum is minimum are %d and %d", arr[min_l], arr[min_r]); }

/* Driver program to test above function */ int main() { int arr[] = {1, 60, -10, 70, -80, 85}; int n = sizeof(arr)/sizeof(arr[0]); minAbsSumPair(arr, n);

getchar(); return 0; }

/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING PURPOSE */ void exchange(int *a, int *b) { int temp; temp = *a; *a *b } = *b; = temp;

int partition(int arr[], int si, int ei) { int x = arr[ei]; int i = (si - 1); int j;

for (j = si; j <= ei - 1; j++) { if(arr[j] <= x) { i++; exchange(&arr[i], &arr[j]); } }

exchange (&arr[i + 1], &arr[ei]); return (i + 1); }

/* Implementation of Quick Sort arr[] --> Array to be sorted si ei */ void quickSort(int arr[], int si, int ei) { int pi; /* Partitioning index */ --> Starting index --> Ending index

if(si < ei) { pi = partition(arr, si, ei); quickSort(arr, si, pi - 1); quickSort(arr, pi + 1, ei); } }

Time Complexity: complexity to sort + complexity of finding the optimum pair = O(nlogn) + O(n) = O(nlogn)

C Language | Set 4
January 11, 2010
Following questions have been asked in GATE CS exam. 1. In the C language (GATE CS 2002) a) At most one activation record exists between the current activation record and the activation record for the main b) The number of activation records between the current activation record and the activation record for the main depends on the actual function calling sequence. c) The visibility of global variables depends on the actual function calling sequence.

d) Recursion requires the activation record for the recursive function to be saved on a different stack before the recursive function can be called. Answer(b) a) > There is no such restriction in C language b) > True c) > False. In C, variables are statically scoped, not dynamically. c) > False. The activation records are stored on the same stack. 2. Consider the C program shown below. # include <stdio.h> # define print(x) int x; void Q(int z) { z += x; print(z); } void P(int *y) { int x = *y+2; Q(x); *y = x-1; print(x); } printf ("%d", x)

main(void) { x=5; P(&x); print(x); getchar(); }

The output of this program is (GATE CS 2003) a) 1276 b) 22 12 11 c) 14 6 6 d) 766 Answer (a) Note that main() and Q() are accessing the global variable x. Inside P(), pointer variable y also holds address of global variable x, but x in P() is its Ps own local variable.

Find the smallest and second smallest element in an array


January 11, 2010

Asked by Vikas Question: Write an efficient C program to find smallest and second smallest element in an array. Difficulty Level: Rookie Algorithm:

1) Initialize both first and second smallest as INT_MAX first = second = INT_MAX 2) Loop through all the elements. a) If the current element is smaller than first, then update first and second. b) Else if the current element is smaller than second then update second
Implementation:
#include <stdio.h> #include <limits.h> /* For INT_MAX */

/* Function to print first smallest and second smallest elements */ void print2Smallest(int arr[], int arr_size)

{ int i, first, second;

/* There should be atleast two elements*/ if(arr_size < 2) { printf(" Invalid Input "); return; }

first = second = INT_MAX; for(i = 0; i < arr_size ; i ++) {

/*If current element is smaller than first then update both first and second */ if(arr[i] < first) { second = first; first = arr[i]; }

/* If arr[i] is in between first and second then update second else if (arr[i] < second) { second = arr[i]; } }

*/

printf("The smallest element is %d and second Smallest element is %d",

first, second); }

/* Driver program to test above function */ int main() { int arr[] = {12, 13, 15, 10, 35, 1}; print2Smallest(arr, 6); getchar(); return 0; }

The same approach can be used to find the largest and second largest elements in an array. Time Complexity: O(n)

Data Structures and Algorithms | Set 9


January 13, 2010

Follow questions have been asked in GATE CS exam. 1 In a heap with n elements with the smallest element at the root, the 7th smallest element can be found in time (GATE CS 2003) a) (n log n) b) (n) c) (log n) d) (1) Answer(c) Given a Min-heap, to get the 7th smallest element, we need to call Extract-Min 7 times which means (7logn)( = (logn)) operations

2. Suppose the numbers 7, 5, 1, 8, 3, 6, 0, 9, 4, 2 are inserted in that order into an initially empty binary search tree. The binary search tree uses the usual ordering on natural numbers. What is

the in-order traversal sequence of the resultant tree? (GATE CS 2003) a) 7 5 1 0 3 2 4 6 8 9 b) 0 2 4 3 1 6 5 9 8 7 c) 0 1 2 3 4 5 6 7 8 9 d) 9 8 6 4 2 3 0 1 5 7 Answer (c) In-order traversal of a BST gives elements in increasing order. So answer c is correct without any doubt.

3. Let S be a stack of size n >= 1. Starting with the empty stack, suppose we push the first n natural numbers in sequence, and then perform n pop operations. Assume that Push and Pop operation take X seconds each, and Y seconds elapse between the end of one such stack operation and the start of the next operation. For m >= 1, define the stack-life of m as the time elapsed from the end of Push(m) to the start of the pop operation that removes m from S. The average stack-life of an element of this stack is (GATE CS 2003) a) n(X+ Y) b) 3Y + 2X c) n(X + Y)-X d) Y + 2X Answer(c) We can easily arrive at the result by taking few examples.

G-Fact 1
January 31, 2010

In C language, sizeof( ) is an operator. Though it looks like a function, it is an unary operator.

G-Fact 2
January 31, 2010

To know the IP address(es) of a URL/website, nslookup can be used at the shell/command prompt (cmd.exe). It works on both types of

operating systems i.e. Linux/Windows. For example, to know the IP address of our website, type nslookup www.geeksforgeeks.org at the shell/command prompt.

G-Fact 3
January 31, 2010

In ISO C, you can define main either to take no arguments, or to take two arguments that represent the command line arguments to the program, like this:
int main (int argc, char *argv[])

Other platform-dependent formats are also allowed by the C and C++ standards; for example, Unix (though not POSIX.1) and Microsoft Visual C++ have a third argument giving the programs environment, otherwise accessible through getenv in stdlib.h:

What all is inherited from parent class in C++?


January 31, 2010

Following are the things which a derived class inherits from its parent. 1) Every data member defined in the parent class (although such members may not always be accessible in the derived class!) 2) Every ordinary member function of the parent class (although such members may not always be accessible in the derived class!) 3) The same initial data layout as the base class. Following are the things which a derived class doesnt inherits from its parent : 1) The base classs constructors and destructor. 2) The base classs friends

Pointer vs Array in C
January 31, 2010

Most of the time, pointer and array accesses can be treated as acting the same, the major exceptions being:

1) the sizeof operator o sizeof(array) returns the amount of memory used by all elements in array o sizeof(pointer) only returns the amount of memory used by the pointer variable itself 2) the & operator o &array is an alias for &array[0] and returns the address of the first element in array o &pointer returns the address of pointer 3) a string literal initialization of a character array o char array[] = abc sets the first four elements in array to a, b, c, and \0 o char *pointer = abc sets pointer to the address of the abc string (which may be stored in read-only memory and thus unchangeable) References: http://icecube.wisc.edu/~dglo/c_class/array_ptr.html

G-Fact 4
January 31, 2010

In C, function parameters are always passed by value. Pass-byreference is simulated in C by explicitly passing pointer values.

Output of C Programs | Set 10


January 31, 2010

Predict the output of the below programs. Difficulty Level: Rookie Question 1
#include<stdio.h> int main() { typedef int i; i a = 0; printf("%d", a);

getchar(); return 0; }

Output: 0 There is no problem with the program. It simply creates a user defined type i and creates a variable a of type i.

Question 2
#include<stdio.h> int main() { typedef int *i; int j = 10; i *a = &j; printf("%d", **a); getchar(); return 0; }

Output: Compiler Error -> Initialization with incompatible pointer type. The line typedef int *i makes i as type int *. So, the declaration of a means a is pointer to a pointer. The Error message may be different on different compilers.

Question 3
#include<stdio.h> int main() {

typedef static int *i; int j; i a = &j; printf("%d", *a); getchar(); return 0; }

Output: Compiler Error -> Multiple Storage classes for a. In C, typedef is considered as a storage class. The Error message may be different on different compilers. Please write comments if you find any of the answers/explanations incorrect, or you want to share more information about the topics discussed above.

References: http://www.itee.uq.edu.au/~comp2303/Leslie_C_ref/C/SYNTAX/typed ef.html http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?to pic=/com.ibm.vacpp6m.doc/language/ref/clrc03sc03.htm http://msdn.microsoft.com/en-us/library/4x7sfztk.aspx

Вам также может понравиться