Escolar Documentos
Profissional Documentos
Cultura Documentos
Lecture-9
Administrative Matters
Advanced Track Results will be announced on Monday Mentoring Please email kvsingh@iitk.ac.in specifying language preferences.
Mentoring Program
Please make an appointment with your mentor before meeting with your mentor. Mentors are students like you (but senior), and have their own academics to take care of.
do-while loop
do-while statement is a variant of while. General form: Execution:
1. 2.
3.
4.
First execute statement. Then evaluate expr. If expr is TRUE then go to step 1. If expr is FALSE then break from loop
statement
TRUE
expr ?
FALSE
Comparative Example-I
Problem: Read integers and output each integer until -1 is seen (include -1 in output). The program fragments using while and do-while.
Using do-while int a; /*current int*/ do { scanf(%d,&a); printf(%d ,a); } while (a != -1); Using while int a; /*current int*/ scanf(%d,&a); while (a != -1) { printf(%d ,a); scanf(%d,&a); } printf(%d , a);
The while construct and do-while are equally expressive (whatever one does, the other can too).
5
Programming Tip
If you are new to C, cultivate your loops programming using one of while or do-while. When you are comfortable with one of them, the other construct becomes easy.
int prev; int curr; int len; int maxlen; scanf(%d,&prev); maxlen = 1; len=1; if (!(prev == -1)) { do { scanf(%d,&curr); if (prev < curr) { len = len + 1; /*extend */ }else{ if (maxlen < len) { maxlen = len; } len = 1; } prev = curr; } while ( !(curr == -1)); } if (maxlen < len) { maxlen = len; }
Problem 2
The first line of the input consists of two positive integers m and n. This line is followed by m lines, each containing n integers, signifying an m X n matrix A. We have to calculate the sum of the squares of the sum of numbers in each row and print it.
i(jAij)2
row i
3 4 4 7 11 2 11 2 4 2 9 0 -1 columns j e.g. A20 = 2, A12 = 2
, i=0..m-1, j =0..n-1.
Double loops
Need something of a double loop here (loop inside a loop). One loop to do the row sum of each row. Once a row is finished, we square the row sum. Another (outer) loop to add the squares of row sum over all rows that have been fully read.
Easy part first: assume we are at the beginning of a row (have not read any numbers yet) and write a loop to calculate the row sum.
int a; /* the current integer */ int colindex; /* index of current column */ int rowsum; /* sum of row entries read so far */ int rowsumsq; /* square of the sum of row entries */ rowsum = 0; colindex=0; while (colindex < n) { /* not finished reading n cols*/ scanf(%d, &a); /* read next number */ rowsum = rowsum + a; /* add to rowsum */ colindex = colindex + 1; /* increment colindex */ } rowsumsq = rowsum * rowsum; /*square rowsum */
10
We have a code that reads the next n integers from the terminal and sums them. Modify it so that it reads the next m integers from the output of the previous code, specifically the value of rowsumsq and sums them.
11
Task: Modify code below so that it reads the next m integers from the output of the previous code, specifically the value of rowsumsq and sums them.
int a; /* the current integer */ int colindex; /* index of current column */ int rowsum; /* sum of row entries read so far */ int rowsumsq; /* square of the sum of row entries */ rowsum = 0; colindex=0; while (colindex < n) { /* not finished reading n cols*/ scanf(%d, &a); /* read next number */ rowsum = rowsum + a; /* add to rowsum */ colindex = colindex + 1; /* increment colindex */ } rowsumsq = rowsum * rowsum; /*square rowsum */
12
Previous code modified to read the next m integers from the output of the previous code, specifically the value of rowsumsq and sums them.
rowsumsq comes from previous code. Lets insert that code here.
13
Initialization and definition can be done together in C. A short-cut. Following code defines an integer variable a and initializes it to 10.
The code int a = 10; defines a (i.e., creates a box named a) and initializes it to 10, both in one single statement. Has same effect as previous code. May be used for any of the basic types, int, float, etc., e.g.,
14
Comma in C
C allows multiple variables of the same type to be defined as one statement, separated by commas. a c a
2
Defines three integer Examples (independent definitions) variables named a,b and c.
int a, b, c;
int a = 2, b = 5, c=15;
Defines three integer variables named a,b and c. Initializes a to 2, b to 5 and c to 15. Compilation error!
b
5
c
15
Defines two float variables named x and y. Initializes x to 3.59 and y to 10.0.
x
3.59
y
10.0
15
16
int m,n; int rowindex = 0; int sqsum =0; int a, colindex, rowsum; scanf(%d,%d, &m,&n); while (rowindex < m) { rowsum = 0; colindex=0; while (colindex < n) { scanf(%d, &a); rowsum=rowsum+a; colindex=colindex+1; } sqsum=sqsum + (rowsum * rowsum); rowindex=rowindex+1; }
Input 2 3 1 0 0 1
m a 1 2
-1 1
3
Output should be 4
0
-1 0 1 1
1
2
1
2 3 0 1 2
1
1 0 0 0 1 2
0
4
17
Suppose we interchange the role of columns and rows. That is, we wish to calculate
Sum of square of column sums Input is same as before: m,n and m X n matrix A, each row of A is given in a separate input line. How can we solve it? Not possible unless a constant fraction of the matrix is stored. (Non-trivial proof).
j ( i Aij)2 ,
i=0..m-1, j=0..n-1.
18
Examples: contd.
1.
2.
3. 4. 5.
Read n,k from input. Check if 0 <= k <= n. First calculate numerator as num = n(n-1)(n-k+1). Next calculate denominator as den = k! Answer is the ratio num/den.
19
20
We used / in n choose k program. The division operator / in C behaves differently for the types int and float. When a, b are both variables of type int, then a/b is the integer quotient when a is divided by b. When a,b are both float, then a/b is the usual (real) division. When one operand is int and other is float, the operand from narrower type is upgraded to wider type. Then
Output
Output
2.500000
21
An alternative computation
Problems with this approach? num may easily become larger than the maximum value of an int although nCk is not large. Then answer is unreliable. Example: consider 25C12 versus 25(24)(23)(13). Another way. Use the identity nC = (n/k) (n-1C k k-1)) and calculate as (n * (n-1Ck-1))/ k Order of evaluation: Multiplication must be done before integer division. E.g, 7C = (7/3) * 15 = (2.3333..)*15 = 35, but there can 3 be loss of accuracy in floating point division. Integer division of course cannot work.
22
Finding an invariant
Using nCk = (n * (n-1Ck-1))/ k First design the loop invariant. Let i be a counter that we plan to increase from i=0,1,2, , k. Maintain a variable ans of type int, which is intended to ultimately hold the final answer nCk . i ans * indicates: multiply previous value of ans by (initially 0) (initially 0) 0 1 2 k
n-k C equals 1 0 n-k+1C 1 n-k+2C 2
* (n-k+1) * (n-k+2)/2 * (n-k+3)/3 * n/k
nC k
23
Invariant: ans = n-k+i C i .Used to design loop. How? Maintain invariant: i will become i+1 in next iteration.
n-k+i+1 C n-k+iC / (i+1) = (n-k+i+1) * i+1 i
main() { int n,k,i,ans; scanf(%d%d,&n,&k); if ((k >=0) && (k <=n)) { /* input is valid! */ ans =1; i=0; while (i < k) { /* loop invariant: ans = n-k+i choose i*/ ans = (ans * (n-k+i+1))/ (i+1); /*int division */ i = i+1; } printf(%d choose %d is %d,n,k, ans); } else { printf(Input parameters out of range); } } /* end of main() */
24
1.
Our invariant was ans = n-k+i C i . An invariant is good for a problem if invariant is ``easily maintained over successive iterations. This is ensured by
,
25
#include <stdio.h> main() { int n,k,i,ans; scanf(%d%d,&n,&k); if ((k >=0) && (k <=n)) { ans =1; i=0; while (i < k) { ans=(ans*(n-k+i+1))/(i+1); i = i+1; } printf(%d choose %d is %d,n,k, ans); } else { printf(Input parameters are out of range); } }
Input 6 3 n 6 ans 1 4 10 20
Output should be 20 k
3 i 0 1 2 3
Output
6 choose 3 is 20
1*(6-3+0+1)/(0+1) = 4 4*(6-3+1+1)/(1+1) = 10
10 * (6-3+2+1)/(2+1) = 20
26
Acknowledgments
These slides are a slightly modified version of the slides by Sumit Ganguly
27