solutions to assessment: arrays, pointers and … 2.pdfsolutions to assessment: arrays, pointers and...

23
Solutions to Assessment: Arrays, Pointers and Strings Question 1: What is the output of the following code segment? char arr[20]="hello world"; printf("%d",sizeof(arr)); Answer: 20 Explanation: The expression sizeof(arr) evaluates to the number of bytes contained in the array ‘arr’ ‘char’ has a size of 1 byte; so sizeof(arr) evaluates to 20. Question 2: Which of the following are valid declarations for an array? More than one choice could be correct. a. int arr[10]; b. int arr[]={1,2,3,4,5}; c. int arr[4]={1,2,3}; d. int arr[5]={1,2,3,4,5}; e. int arr[5]={1,2,3,4,5,6}; Answer: a, b, c, d Explanation: option (a) is a standard way of declaring an array (b) is valid because we need not specify the size of the array if we are initializing the array with some elements. The size is automatically inferred by the compiler. c) and (d) are also valid declarations because number of elements on RHS <= size of array (e) is not valid because number of elements on RHS exceeds the size of the array Question 3: What is the output of the following code segment? 1. int temp,i,j; 2. int num[7]={7,6,5,4,3,2,1}; 3. for (i=1; i<6; i++)

Upload: dangnhan

Post on 13-May-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

Solutions to Assessment: Arrays, Pointers and Strings Question 1: What is the output of the following code segment? char arr[20]="hello world"; printf("%d",sizeof(arr)); Answer: 20 Explanation: The expression sizeof(arr) evaluates to the number of bytes contained in the array ‘arr’ ‘char’ has a size of 1 byte; so sizeof(arr) evaluates to 20. Question 2: Which of the following are valid declarations for an array? More than one choice could be correct. a. int arr[10]; b. int arr[]={1,2,3,4,5}; c. int arr[4]={1,2,3}; d. int arr[5]={1,2,3,4,5}; e. int arr[5]={1,2,3,4,5,6}; Answer: a, b, c, d

Explanation: option (a) is a standard way of declaring an array

(b) is valid because we need not specify the size of the array if we are initializing the array with some elements. The size is automatically inferred by the compiler. c) and (d) are also valid declarations because number of elements on RHS <= size of array

(e) is not valid because number of elements on RHS exceeds the size of the array

Question 3: What is the output of the following code segment? 1. int temp,i,j; 2. int num[7]={7,6,5,4,3,2,1}; 3. for (i=1; i<6; i++)

4. for (j=0; j<6; j++) 5. { 6. if(num[i]>num[i+1]) 7. { 8. temp=num[i]; 9. num[i]=num[i+1]; 10. num[i+1]=temp; 11. } 12. } 13. for (i=0; i<7; i++) 14. printf("%d",num[i]); Answer: 7543216

Explanation: For every iteration of ‘for’ loop in line 3, if(num[i] > num[i+1]){} on line 6 is executed 6 times(due to the ‘for’ statement in line 4) for every i. After one iteration of ‘for’ loop in line 3, the contents of array will be {7,5,6,4,3,2,1}; arr[1] and arr[2] in the original array are swapped. After second iteration, arr[2] and arr[3] will be swapped because arr[2] > arr[3]. The contents will be {7,5,4,6,3,2,1} and so on…

At the end of 5 iterations, the contents of the array will be {7,5,4,3,2,1,6}. Therefore the answer will be 7543216

Question 4: What is the output of the following code segment? int i; int num[3][5]={1,2,0,4,5,{6},{3,7,10}}; printf("%d %d %d %d",num[0][3],num[1][2],num[2][0],num[2][4]); Answer: 4 0 3 0

Explanation: num[3][5] = {{1,2,0,4,5}, {6,0,0,0,0},{3,7,10,0,0}}; //All these 15 integers are stored in contiguous locations in memory.

num[i][j] = *(*num + i*numColumns+j) //Using indices i and j; we can find the exact address of the element we want num[0][3] = *(*num+0+3) = 4 //Address of the element num[0][3] = *(*num+3) num[1][2] = *(*num+5+2) = 0 //Address of element num[1][2] = *(*num+7) num[2][0] = *(*num+10+0) = 3

num[2][4] = *(*num+10+4) = 0 Question 5: What is the output of the following code snippet? Mention your answer as <error> if you think that the code fragment results in a compile-time error. int arr[3][2]={{1,2},{3,4},{5,6}}; printf("%d %d %d",arr[0][3],arr[1][2],arr[2][0]); Answer: 4 5 5 Using similar logic as in the above question: arr[0][3] = *(*arr + 0*2 + 3) = 4 //arr[1][1] = *(*arr+1*2+1) = *(*arr + 3) = 4 arr[1][2] = *(*arr + 1*2 + 2) = 5 arr[2][0] = *(*arr + 2*2 + 0) = 5 Question 6: What is the output of the following code snippet? Mention your answer as <error> if you think that the code fragment results in a compile-time error. 1. int x = 5, y = 15; 2. int * p1, * p2; 3. p1 = &x; 4. p2 = &y; 5. *p1 = 10; 6. *p2 = *p1; 7. p1 = p2; 8. *p1 = 20; 9. printf("%d %d",x,y); Answer: 10, 20

Explanation: In line 5, *p1 = 10; so the value of variable x is changed to 10. In line 6, *p2 = *p1 → value of variable y is changed to 10

In line 7, p1 = p2 → pointer p1 points to variable y now

In line 8, *p1 = 20 → value of variable y is now changed to 20

Question 7: What is the output of the following code snippet? Mention your answer as <error> if you think that the code fragment results in a compile-time error. int num[5] = {0,0,0,0,0}; int * p; p = num; *p = 1; p++; *p = 2; p = &num[2]; *p = 3; p = num + 3; *p = 4; p = num; *(p+4) = 5; int n; for (n=0; n<5; n++) printf("%d",num[n]); Answer:12345 Explanation: Observe that the loop variable n in the last for loop varies from 0 to 4. So what is getting printed is num[0] to num[4]. Now, the following points explains why the output is 12345. 1. Name of an array points to the starting location of the array. 2. * of a <pointer variable> represents the memory location pointed by the <pointer variable>. 3.. Adding a constant c to a pointer variable p results in adding c*size of (<data type of p>) to p. Which logically means making p to point to the c^th location of same type starting from the current location pointed by p. 4. & of a <variable> represents the address of the <variable>. Question 8: Consider the following code: int a[1] = {34}; // Line 1 int b = (int) *a; // Line 2 int c = (int *) a; // Line 3

int d =(long ) a; // Line 4 int e = (int) a[0]; // Line 5 Which of the following four variables get the value 34? Pick ALL the correct answers. Options: b c d e Answer: b and e Explanation: 1. First line declares an array of size 1 and initialize the starting location with 34. 2. b gets the contents of the location pointed by a which is basically a[0]. 3. c gets the contents of the location a, which is basically equivalent to address of a[0], type casted to integer pointer. 4. d gets the content of the location a, which is basically equivalent to address of a[0], type casted to long data type. 5. e gets the content of the location a[0], which is 34, type casted to int data type. Question 9: What will be the output of the following program? #include <stdio.h> int main() { int x1 = 10; int *x2, **x3, ***x4; x2 = &x1; x3 = &x2; x4 = &x3; printf("%d%d%d%d", (x1==10), (*x2==10),( *x3==10), (***x4==10) ); } Options: 0000 1110 1101 Compilation Error Answer: 1101

Explanation: x2 is a pointer to x1. x3 is a pointer to x2 which implies x3 is a pointer to pointer to x1(implies **x3 represents location x1). x4 is a pointer to x3. This implies x4 is a pointer to pointer to pointer to x1(implies ***x4 represents location x1). *x3 represents address of x1 but not x1. That is why the third digit is 0. A logical statement returns 1 or 0 depending on whether the statement is true or false. Question 10: In the piece of code, arr[ ][ ] is a 2-D array and assume that the contents of the 2D array are already filled up. What is stored in the variable sum at the end of the code segment? int arr[3][3]; int i, sum=0; i = 0; while(i<3) { sum += *(*(arr+i)+(i++)); } printf("sum:%d", sum); Options: Sum of all elements in the matrix Sum of alternate elements in the matrix Sum of the elements along the principal diagonal None of these Answer: Sum of the elements along the principal diagonal Explanation: Observe that the unary operator ++ in the program is a post increment operator. Thus the value of i gets incremented only after the execution of the statement. Since arr is a 2-D array, arr represents a pointer to an array of pointers, where each pointer in the array in turn points to a 1-D array(i^th pointer points to the starting location of i^th row in the array). So, *(arr+i) represents the starting address of i^th row. This implies *(arr+i)+i represents the address of i^th element in the i^th row, which is basically a diagonal element. Question 11: Consider the following code. What will be its output? #include <stdio.h>

void main() { char *a="HELLO\0 HI"; printf("%s",a); } Options: HELLO\0 HI HI \0 HELLO Answer: HELLO Explanation: The format specifier %s expects a character array(string) as the parameter and it prints the contents of the array character by character till it finds a ‘\0’ character. This is basically used as an end marker to indicate the end of the valid data to be printed. Question 12: Consider the program segment given below. int a=10; int *p; p=&a; *p++; printf("%d", *p); Which of the following are correct at the end of the segment? Mark all the correct answers. Variable a will contain value 10 Variable a will contain value 11 Pointer p points to a Pointer p does not point to a Answer: 1st and 4th options are true. Explanation: In line 5, the dereference operator(*) has lower precedence than post increment operator ++. Thus, the equivalent parenthesized expression is *(p++). Thus p gets pointed to the location next to a and a has the value 10 itself. Question 13: What is the output of the program segment below? char str[4] = “abe”;

char c = ‘d’; char tmp = ‘f’; tmp = str[0]; str[0] = ‘c’; c = tmp; printf(“%c%c%c”,str[0],c,tmp); Answer: caa Explanation: After the initializations, the values of str[0], c, tmp variables are as follows: str[0] = 'a' c = 'd' tmp = 'f' After the execution of each statement, the values change as shown below and hence the result. tmp = str[0]; //line 4 str[0] = 'a' c = 'd' tmp = 'a' str[0] = ‘c’; //line 5 str[0] = 'c' c = 'd' tmp = 'a' c = tmp; //line 6 str[0] = 'c' c = 'a' tmp = 'a' Question 14: Consider the code segment given below. #include < stdio.h > int main(){ char *str1 = "Hello World"; char *str2 = "Hello"; if(*str1 == *str2) printf("Here"); else printf("There"); return 0; } Answer: 1. Prints Here on the screen Explanation: str1 contains the memory address of first element of the string "Hello World". str2 contains the memory address of first element of the string "Hello". *str1, *str2 gives the first characters of both the strings which are 'H' and 'H' and hence the result.

Question 15: Assume that characters occupy 1 byte and pointers take 8 bytes. What is the output of the following program? #include < stdio.h > int main(){ char char_array[]="Hello\0World"; char *str="Hello\0World"; printf("%s %c\n",char_array,char_array[1]); printf("%s %c\n",str,str[1]); printf("%d %d\n",sizeof(char_array),sizeof(str)); return 0; } Answer: 3. Hello e

Hello e 12 8

The %s in printf prints the characters of stream until it doesn’t find any null character (‘\0’). Since the str and char_array have '\0' after Hello, first and second printf statements prints the same output. A character array contains every element of an assigned array but a character pointer contains the memory address of first element. But the size of an array is the total number of its elements i.e. 12 bytes (including null character). While the size of pointer is 8 bytes.

Solutions to Programming Assignments

Question 1: Most Frequent Element in a Sequence Write a program to read a sequence of N integers and print the number that appears the maximum number of times in the sequence. INPUT: Input contains two lines. First line in the input indicates N, the number of integers in the sequence. Second line contains N integers, separated by white space. OUTPUT: Element with the maximum frequency. If two numbers have the same highest frequency, print the number that appears first in the sequence. CONSTRAINTS: 1 <= N <= 10000 The integers will be in the range [-100,100]. Public test cases: Input Output

5 1 2 1 3 1

1

6 7 7 -2 3 1

7

4 2 3 2 3

2

Private test cases: Input Output

3 1 12 -1

1

1 12

12

5 4 2 4 3 4

4

6 10

Comment [1]: I've inserted page-breaks between two consecutive programming assts, so that each programming asst starts in a new page

Comment [2]: Nice da. But when I publish to the web, I may need to remove them because they are not rendered properly. Will comment back on this to let you know.

Comment [3]: Nope, didn't need to remove them, the page was rendered fine.

303 10 2 10 1 1

4 1 1 1 1

1

4 2 1 1 1

1

8 123 -1 2 21 1 2333 -1 -1

-1

2 10 1

10

Solution: #include<stdio.h> int main() { int n, i, j; scanf("%d", &n); int arr[n]; for(i = 0; i < n; i++) { scanf("%d", &arr[i]); } int freq = -1, maxEl = 0,tempFreq = 0; for(i = 0; i < n; i++) {

//tempFreq stores the frequency of element arr[i] in the sequence

tempFreq = 0; for(j = i; j < n; j++) { //counting frequency of arr[i] only on the right side of i is enough; since if arr[i] occurred on left side of i, it’s frequency would have been more anyways if (arr[i] == arr[j]) { //if you encounter element equal to arr[i], increment tempFreq; tempFreq++; } } if (tempFreq > freq) { //variable freq stores the maximum frequency that has been encountered so far //maxEl stores the array element that has the maximum frequency encountered so far freq = tempFreq; maxEl = arr[i];

} } printf("%d", maxEl); }

Question 2: Print Elements of a Matrix in Spiral Order Write a program that reads an MxN matrix A and prints its elements in spiral order. You should start from the element in the 0th row and 0th column in the matrix and proceed in a spiral order as shown below. 1→ 2→3→ 4 ↓ 5→ 6→ 7 8 ↑ ↓ ↓ 9 10←11 12 ↑ ↓ 13←14←15←16 Output for the above matrix: 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 INPUT: First line contains two integers M and N separated by whitespace. The next M lines contain elements of matrix A, starting with the topmost row. Within each row, the elements are given from left to right. OUTPUT: Elements of the matrix printed in a spiral order. All the elements should be separated by whitespace. CONSTRAINTS: 1 <= M <= 5, 1 <= N <= 5. Elements in the matrix will be in the range [-100,100] Public Test Cases: Input Output

3 3 0 1 2 7 8 3 6 5 4

0 1 2 3 4 5 6 7 8

2 2 1 10 3 5

1 10 5 3

4 4 7 8 1 2 3 4 3 1 1 2 8 6 5 4 9 7

7 8 1 2 1 6 7 9 4 5 1 3 4 3 8 2

1 1 20

20

Private Test Cases: Input Output

3 3 1 2 3 4 5 6 7 8 9

1 2 3 6 9 8 7 4 5

2 4 1 2 3 4 5 6 7 8

1 2 3 4 8 7 6 5

3 4 1 2 3 4 5 6 7 8 9 10 11 12

1 2 3 4 8 12 11 10 9 5 6 7

1 2 1 20

1 20

2 2 1 -1 2 3

1 -1 3 2

3 1 1 2 3

1 2 3

1 4 1 2 3 4

1 2 3 4

5 5 1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

1 2 3 4 5 1 15 20 25 24 23 22 21 16 11 6 7 8 9 14 19 18 17 12 13

Solution: Please see the video (can be found here: http://youtu.be/EK4OUYVL5HE) which discusses the solution shown below: #include<stdio.h> int main() { int A[5][5]; int B[25]; int M, N; int i,j; int cnt=0; int cnt1=0; int top, bot, right, left; scanf("%d%d",&M,&N); for(i=0; i<M; i++){ for(j=0; j<N; j++){ scanf("%d",&A[i][j]); } } top = 0; bot = M-1; left = 0; right = N-1; for(cnt1=1; cnt1 <= M/2 && cnt1 <= N/2; cnt1++){ for(i=left; i<= right; i++){ B[cnt++]= A[top][i]; } for(i=top+1;i<=bot;i++){ B[cnt++]= A[i][right]; } for(i=right-1; i>=left; i--){ B[cnt++]= A[bot][i]; } for(i=bot-1; i>=top+1; i--){ B[cnt++] = A[i][left]; } top++; bot--;

left++; right--; } if(top==bot && left==right){ B[cnt++]=A[top][left]; } else if(top<bot){ for(i=top;i<=bot;i++){ B[cnt++]=A[i][left]; } } else if(left<right){ for(i=left; i<=right;i++){ B[cnt++]=A[top][i]; } } for(i=0;i<M*N-1;i++){ printf("%d ",B[i]); } printf("%d",B[i]); return 0; }

Question 3: Maximum Sum of Rows, Columns and Diagonals Write a program that reads an NxN square matrix M that calculates the sum of the elements in individual rows, individual columns and the two main diagonals. Among these sums, print the largest. Consider the following matrix of order 3x3: 1 10 13 2 14 12 3 9 8 The row sum values are 1+10+13=24, 2+14+12=28 and 3+9+8=20. The column sum values are 1+2+3=6, 10+14+9=33 and 13+12+8=33. The diagonal sums are 1+14+8=23 and 13+14+3=30. The expected output is maximum among these sums, which is 33. INPUT: First line contains a value N representing the dimension of the input matrix M, followed by N lines, each line representing a row of the matrix. Within each row, N values are given and are separated by whitespace. OUTPUT: A value which is the maximum among N row sums, N column sums and the two main diagonal sums in M. CONSTRAINTS: The entries in M are integers. 1<=N<=100 -100 <= Mij <= 100 Public Test Cases: Input Output

3 1 2 3 5 -6 7 9 10 -3

16

2 16 4 -3 5

21

4 1 2 3 4 5 6 7 18 9 1 1 12 13 14 15 -60

36

Private Test Cases: Input Output

3 1 2 3 4 5 -6 7 -8 9

15

1 100

100

2 100 1 2 -100

102

5 1 12 12 14 -100 1 30 10 14 20 35 22 14 11 4 45 2 44 4 5 23 12 4 2 14

105

2 -1 -2 -4 -8

-3

Solution: #include<stdio.h> int main() { int a[100][100];//input matrix int n;//dimension of the square matrix int i,j;//loop variables int sum=-10001;//variable that holds the maximum among a set of rows/columns/diagonals that are considered so far int temp_sum;//variable that holds partial sum of values in a row/column/diagonal scanf("%d",&n); //read dimension

for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&a[i][j]);//read input values for(i=0;i<n;i++) { temp_sum=0;//reset the variable before storing the partial sum of values in a row under consideration for(j=0;j<n;j++) { temp_sum=temp_sum+a[i][j]; //calculate the sum of elements in the i^th row } if(temp_sum>sum)//check whether the sum of values in the i^th row is better than the current maximum { sum=temp_sum; } } for(i=0;i<n;i++) { temp_sum=0;//reset the variable before storing the partial sum of values in a column under consideration for(j=0;j<n;j++) { temp_sum=temp_sum+a[j][i];//calculate the sum of elements in the i^th column } if(temp_sum>sum) { sum=temp_sum;//check whether the sum of values in the i^th column is better than the current maximum } } temp_sum=0;//reset the variable before storing the partial sum of values in the first diagonal for(i=0;i<n;i++) { temp_sum+=a[i][i];//calculate the sum of elements in the first diagonal }

if(temp_sum>sum) { sum=temp_sum;//check whether the sum of values in the first diagonal is better than the current maximum } temp_sum=0;//reset the variable before storing the partial sum of values in the second diagonal for(i=0;i<n;i++) { temp_sum+=a[i][n-1-i];//calculate the sum of elements in the second diagonal } if(temp_sum>sum) { sum=temp_sum;//check whether the sum of values in the second diagonal is better than the current maximum } printf("%d",sum); return 0; }

Question 4: Substrings Write a program that takes two input strings S1 and S2 and finds if S2 is a substring of S1 or not. If S2 is a substring of S1, the program should print the index at S1 at which there is a match. If S2 is not a substring of S1, the program should print -1. If S2 appears in S1 multiple times, print the first index in S1 at which the match occurred. INPUT: Two strings S1 and S2, separated by whitespace. OUTPUT: One integer, which is either the index at which the match occurred or -1. Remember, the indices start at 0 for arrays. CONSTRAINTS: Each string contains at most 19 characters. The strings will contain only letters from the alphabet (a-z and A-Z). Match has to be case-sensitive. Public Test Cases:

Input Output

football foot 0

mickey mouse -1

abcdefghijklmnopqrs s 18

helloworld helloworld 0

FrodoBaggins bagg -1

Hell Hello -1

coolgoose oo 1

Private Test Cases: Input Output

abcdefghijklmnopqrs srqponmlkjihgfedcba -1

treat treats -1

reduce duce 2

oneonone on 0

OneonOne on 3

a a 0

Solution: #include<stdio.h> #include<string.h> #define MAXLENGTH 20 #define INVALID_POSITION -1 int main(){ char str[MAXLENGTH]; char substr[MAXLENGTH]; scanf("%s%s",str,substr); // scan the string and the substring int size_of_str = strlen(str); int size_of_substr = strlen(substr); int str_index=0; int substr_index=0; /* position of match. initialized to -1*/ int position_of_match = INVALID_POSITION; /* Search till the end of string or till a match is found. */ while(str_index<size_of_str){ /* Match first character of sub string. Once the first character is matched check if the required substring starts there. */ if(substr[0] == str[str_index]){

for(substr_index=1;substr_index<size_of_substr;substr_index++){ if((str_index+substr_index)>= size_of_str) break; // We have reached the end of string before end of substring. No match... if(substr[substr_index] != str[str_index+substr_index]) break; // a miss match between two strings at this position. No match here. }

if(substr_index == size_of_substr){ // Great!!! we have matched the string position_of_match = str_index; break; // we have got the match. Now stop searching.

Comment [4]: cleaned up code. Has ran this code in nptel mooc.

} } str_index++; } printf("%d",position_of_match); return 0; }