 Good morning and welcome back again. So, in the morning we saw examples of the use of an array. Now, another important use is to handle character strings. String, notice that we have not yet introduced string as a data type yet and that is because the programming language C does not provide for string as a data type directly. Instead, it provides for a data type called care which stands for character. Unfortunately, even the character data which is handled inside C is actually somewhere between an integer and character and the C programming language very loosely distinguishes between integer and character. As a matter of fact, most of the characters are internally treated as integers. Since the character strings in C require the use of arrays, so far we avoided the explicit discussion of strings and string handling. However, now equipped with the discussion on arrays, we can see how arrays are utilized to handle character strings and therefore, we introduce the character data type in C. First of all, the character constants. How are the constants written in our program? In our program, the character constants are written as a single character within quotations, so like what you see here. So, I have small a in a single code. Please note this is different from writing a string. I can write strings in my output operations and so on but we are now talking about data value. So, an individual character as a data value will have to be indicated like this. So, internally it is represented as an integer and it occupies one byte in our storage which is the smallest addressable unit of memory. Now, typically the representation of characters is done using an ASCII code. You are all familiar with ASCII code but for our students we will have to tell them that it is one byte long and these are typical decimal values of the ASCII code for some of the well known characters alphabets A to Z, capital A to capital Z. It is useful to tell them what backslash stands for the new line character whose value is 10. And of course, then one can declare variables in a program of type care by saying the keyword care instead of int or float and then describing as many variables as you want. As usual with numerical variables you can initialize character variables to character values. Please note and I repeat and you must repeatedly tell your students that these variables do not store strings. Each variable can store exactly one character and nothing else. So, therefore, just like an integer and a float has a size limitation and any number value any value greater than that cannot be stored. So, it is here anything other than a single character cannot be stored here. If I want to handle strings then I will necessarily have to use some kind of mechanism which will permit me to look at a set of characters as a single entity and we know that that feature is an array. And therefore, the traditional way of representing character strings not only in C but even in C plus plus because C plus plus uses extended features is to use a care array. You should also note that the C plus plus language permits string as a separate set of objects and has a huge object library to handle strings there. But as far as C is concerned you describe a care array as let us say employee first name 60. So, this would be an array which can hold 60 by 60 individual characters. However, a peculiar feature of C arrays is that to determine how many characters are there in an actual string which is stored inside an array C uses a very funny notation at the end of an actual string it puts a null character. So, backslash 0 is a special character which is inserted at the end of a string. Consequently, if you have a 60 element array it is perfectly possible for you to store a string with let us say only 17 characters in which case the 18th character will be a backslash null. If you somehow get a string constant inside that array the backslash null will be inserted by C. If however you are manipulating the array then it is your responsibility to ensure that at the end of any string you necessarily insert a backslash 0. This backslash 0 now is like a flag. So, if you are examining what is the actual string inside an array you keep looking at every character and the moment you encounter a backslash 0 you know that the character string has ended. So, here is an example if I have a name with 60 elements it can hold 59 characters. However, if I want to store the name of my friend Rajesh Mahshuvala into this array I cannot directly make this statement that is not permitted in C because this is not a variable scenario. Instead each location will have to be assigned a simple value corresponding to a character. So, I will have SNM 0 containing R SNM 1 containing A and so on. And since there are 16 characters in this string including the blank to indicate that the string has finished the 17th character will have to be inserted with a value backslash 0. Since backslash 0 or null value is the last element of an array in a representative string such strings are called null terminated strings. Please note C provides absolutely no protection against your messing up the array. For example if you have a 60 element array and you try to store 80 characters in it C will not shout at you at all it will quietly store the first 60 characters in the 60 elements. The 60 first element will be stored in the next consecutive location it will chew up your own program or some other data. So, you have to be extremely careful the program must guard against such intruders. I wanted to discuss other issues here. May I now go over to the quiz. So, let me demonstrate to you the use of clickers. So, here is a quiz. First of all let me request once again all the remote centers I hope you have loaded the client software in the system and you have connected the hardware. I now request all participants to switch on their clickers by pressing the S T button. In case you already pressed S T button sometime ago the clicker might dangerously just shut off before you answer. So, in such cases press reset button and press S T button once again. I hope all of you have done that. Now I will ask him to once again let me just go through the quiz is very simple. We all know computers have memory to store instructions in data. This is a question about history. So, do not be worried about giving wrong answers. Which technology was used in the earliest digital computer? The choices are A magnetic core, B electronic walls, C semiconductor memory, D cathode ray tube and E none of these. We are setting the time to 2 minutes. Your time starts now. Okay this is over now. So, this is actually the clicker interface. These choices can you collect the okay. We still have a problem with several centers but the crosses that you see here are the centers from which the responses have been collected. I do not know whether you are familiar with what we are doing. Each remote center has a receiver which collects all the clicker responses there. Then we have a comprehensive layer of socket programs at separate team laid by Jayanth Bansal that developed it. So, what happens is then all these responses come back here. So, even if you do not see a cross in one of the fields it does not mean that the responses have not been collected. The mechanism that we adopt in such cases is asynchronous. At the end of the day all responses collected during the day for all quizzes are collected together and a single file is FTP here and the same software then it can consolidate. So, teacher does get the feedback. In this case we will see how much feedback you have got. So, can you view the responses? Just show the bar chart. Wow! I did not know that people have so many different types of I mean the people seem to be equidistributed in their this is very remarkable. So, let me analyze this quiz because apart from historical significance is also important for our colleague teachers to know the correct answer because some smart student may ask this question. So, I will repeat the question. The question actually relates to Manchester Mark 1 which was the first digital computer to run a program. There were multiple computers being developed in US and UK but the first one to actually run a program was in England at that time it was I think June of 1946 and that computer used the very funny kind of memory. So, let us look at the options again. Choice A said magnetic core and not incorrectly many people have shown that as an option because all of us know that the early computers used magnetic core as the memory. However I am talking about 1946 and not 1955. So, magnetic core memory was not available then as a technology. Choice B says electronic walls and several people guess rightly that electronic walls where the technology used to build the digital circuits. So, maybe this was used in memory but that is not a correct answer because digital walls were never used to build the electronic circuits in the computers but they were never used to build the computers memory. The third choice which actually has either the largest number or almost 50 percent number 50 people that is say semiconductor memory that choice is wrong and I would remind our colleague teachers to remember that although they might be very young the time that we are talking about this semiconductor technology had not yet arrived in the world. So, there were no semiconductors and therefore there was no semiconductor memory. There are about 12 people who believe that cathode rate you was used. I do not know whether they have said this confidently because they actually know this is the right answer and incidentally this is the right answer or because they use the elimination technique in all multiple choice quizzes and they said that this could not be there, this could not be there, this could not be there and since Professor Fartag is asking the question none of this should not be there and therefore they said this is this is the kind of smartness most of my students employ and that is why we hesitate in giving multiple choice quizzes in all of our courses. But anyway the correct answer is cathode rate tube indeed those of you who have done electrical engineering would recognize that both the cathode rate tube and the notion of capacitance. So, the cathode rate tube used to display either a dot or a dash and whether it was a dot or or a dash was detected by a capacitance which was sort of measured just on the surface of the cathode rate tube and the memory had to be stable that means you should be able to say that I have stored zero there and the zero should be readable even after some time. It was only on a cathode rate tube that they could consistently keep by refreshing a display of either a dot or a dash anyway will not go into those technology details. The objective here primarily was to confirm that yes we are actually using this technology in a distributed fashion. So, with this I will say thank you to all my participants and thank you to all dignitaries lecture here. So, let me go back to that arrays can be used to represent character strings in C and there is no concept of assigning a name or a string directly to an array. So, we must put individual characters inside a location and further since the string which is stored in this fashion is not a predefined data type we cannot perform normal operations like assignment comparison concatenation etcetera. Something special just like we discussed the implementation of high precision numbers where we said we will have to implement operations ourselves whether you want to add or subtract numbers. Similarly, strings represented in this artificial manner or a special manner I would not say artificial because some similar way has to be found anyway where null terminated strings will have to be handled by us all such operations will have to be written by us. Consider this for example I want to find out the length of the string which is stored in S name consider Raj Mashtoala was stored in that string S name I do not know of course what is inside. So, how do I find out the length? Simple I start looking at every character in sequence whenever I encounter backslash 0 which is a null I know that there are no more characters and I complete my count. So, here is a small code written to demonstrate how I can find out the length of a string. So, I say int I length for I equal to 0 S name I not equal to backslash 0 I plus plus continue. Please notice that this continue statement merely means go ahead actually even if I had not written continue it would have continued automatically to execute this particular block there has to be some statement whenever I write it like this. Now, what it will do is it will start the loop with I equal to 0 will then examine 0th element 1st element 2nd element and so on every time it will check this condition is the Ith element not equal to backslash 0 that means it is not null that means it some other valid character it will continue somewhere this condition will become untrue when actually it will encounter a null when it encounters a null at that point whatever is the value of I those many characters are there how because the I value is actually the index of an element where the null is stored but remember that we start with 0 consider for example S name 17 is null I will be then 17 when I come out I am assigning 17 to length and that is indeed correct because if S name 17 is null that means they were valid character still S name 16 but since it started with 0 the total number of valid characters in the string is still 17 0 1 2 3 up to 16 so this is the correct logic this is how you would have to implement a variety of functions fortunately the C programming language permits us another standard library called string library if we say hash includes string.h then all those functions become available to us I have listed some of the functions here I do not want to go into the details of these at this juncture but you should experiment with the usage of these functions for example string copy permits you to copy a string into another one string cat permits you to actually concatenate two strings strlel is that is the function which does what we just saw please notice therefore that some of these functions are available and even we can write the code for these functions however life is made easier if there is a standard library which permits us to use these functions there are other functions strcmp as the name suggests it compares strings the comparison is said to be lexicographic the lexicographic comparison means that just as we said numerical comparison we know 5 is greater than 4 20 is greater than 19 etc but when we have character string how do we decide which character is greater than another character so as we know as key code defines numerical values for these and whichever is a higher code that is a higher value the ordering of characters intrinsically defined by such standards is called lexicographic all so there is a lexicographic comparison and it compares two strings if there is a string that is found then it will it will return a value which is less than 0 if one string is smaller is 0 if both strings are same and positive otherwise so this is how you can compare two strings str str actually searches a string inside of another string strchr searches for a character inside a string so suppose there is a string in which you want to locate a comma because somebody has said that the string contains two values separated by a comma now I want to separate out the characters belonging to first part and characters belonging to second part I must search for that comma I can do that search for comma by using strchr function what it does is it searches for str and returns a value which indicates the index of that one character inside here many count characters from str into s1 there are functions which actually examine individual characters and decide whether this character is numeric alphabetic or whatever whatever so these are like examination characters you can say is all dume is alpha is cntrl is digit as the name would suggest the first one will check whether the character being examined is alphanumeric or the character being examined is alphabetic similarly it can test for lower case upper case where exactly do we need to use these functions in case we are writing an application which requires to extensively handle text for example somebody is building an editor or somebody is building a word processor all of these things will have to be done always additionally most compilers which have to look at your program as a text they will have to do a lot of flexible analysis of the text that you input please remember the flexibility that you have you can start writing comment at the end of any sentence you can put one space or you can put five spaces you can put a tab all of these will have to be analyzed you you may put a number when you you you may put a alphabetic character when you are supposed to put a number so within a number if you if the compiler encounters a character said for example mistakenly tied by you you can't expect the compiler to crash but you expect compiler to say that the constant that you have typed in at this particular point line number so and so is not a valid numerical value which is required there in order to say that what the compiler would do is that it will examine the entire line that you give and at a place where a value is expected numerical value is expected it will first examine every individual character whether it is numeric or not if it is not numeric it will shout at you otherwise it will actually translate the value proper all of these things so anybody any program which requires heavy handling of text in some form or the other would need to use these so there are these and many other functions and you have an extremely rich library to handle characteristics here the next example that I want to consider is that of searching searching of values inside arrays and since such searches are very rapid in case the arrays are sorted the accompanying problem of sorting arrays are considered extremely important in any information processing activity it is important for scientific computations when you have very large values to handle it is important for industries where you have to again handle very large number of records so sorting and searching forms a very special topic in computer programming it is discussed in the first course it is discussed in a course in algorithms it is discussed in the course in data structures where special data structures which help this sorting could be handled so it is an important topic all that we are trying to indicate at this stage is how a simple searching mechanism works you will recall that I had one particular problem that suppose the programming but when I was defining the context of human interaction where I had said that somebody and the role numbers are given and their marks are given and that is in the increasing order of role numbers however he wants his assistant to find out whether a student certain student whom he knows as how many marks that student has and suppose he gives to his assistant a list of these marks and role number not in arrange in ascending order of role number but arrange in descending order of marks which is another way of sorting after all I want to put the top performer at the first position then the next then the next and the lowest performer at the bottom so that is called merit list so suppose he gives a merit list and say find out whether this fellow is there or not and we said in either case the assistant will have to go through each and every number match it against the given role number and find it out so far we had no mechanism to store a set of role numbers or a set of marks conveniently array permits us to do that once I have an array therefore I might choose to store a list of role numbers in an array and the list of corresponding marks in another array so if I have an array with role numbers and array with marks I have read the data once and now that friend of mine says find out whether this particular role number exists or not so how do I check whether a given role number exists inside the array or not that is the first question is a computational problem and more interesting problem is if this list is very big how long it will take to do this checking and can I make it faster so let us look at a line of code which actually find marks dot cpp I have named it it is not a full program it is just a segment eventually we will upload a full program on to the website this is not you don't need it today so don't worry about it but it will come on the moodle eventually so let us see what we are trying to say here given a role number find the marks and I am presuming that there are may be up to 100 students so their role numbers are stored in an array called role marks are to be stored in an array called marks end students represent the number of students and I have decided to use additional variables here given role should naturally represent the role number which is given by someone which he wants me to search found marks obviously would be a variable which will contain the final marks corresponding to that given role number there is also a position which will probably indicate the position of that student not the buried position position of that student localize a position of that student inside the array so there are 100 elements whether it is the 53rd element which contains the given role or 25th etcetera I is an index with this explanation let us look at the algorithm itself it is pretty simple I have said read all the data in array so please note this program that is why it said it is a segment it is not a full program so how will you actually read all the data very simple you can set up an iteration first read the value of end students set up an iteration I equal to 0 to end students and in each iteration read a value of role I and a value of marks that simple as that once you have read all the values then the program starts here we want to find out the problem I restate we want to find out whether a given role number has passed the exam and how many marks that person has got so here is the code for it I read the given role number see in greater greater given role now I set up an iteration which will go over to all the existing elements of the role number array please note the role number array is defined to have 100 elements however the number of students whose data has been read is only end students so I will set up an iteration which will vary I from 0 to end students minus 1 again please remember in case of arrays it is not only counting that I am doing but my index expression will itself be formed by the variable that I use in my statement and therefore invariably you will find that iterations which are controlled for moving or doing passes over array elements typically will begin with 0 and will end with end minus 1 if n is the total number of elements as you can see here the iteration is from I equal to 0 to I less than end students which means the last value that I will take is end students minus 1 which will be actually the role number of the last student and of course I plus plus is the standard increment at the end of the loop what do I do within the loop if Ith role number is given role somebody says find out marks for 1005 now role number 1005 I don't know where I put it so I will compare the given role with every element of role somewhere I will find that student whenever I find that student I will take the corresponding marks role I is equal to given roles therefore marks I contains the marks of that student please understand that this is not explicit see language or program or computer doesn't know it but it is the way I have organized it so if I have to arrange it is legitimate that I put data very carefully in corresponding location fifth location as a role number the fifth location other array must have marks of the same student there is no check on these things it is my responsibility to do that having done that I will say found marks is this when I go through this entire iteration when I come out I would have got a value for found marks all that I do is I print out marks for given role or found marks and then I will return to you some problems in this code consider for example that I have found marks the second time itself now unfortunately even after I find the fellow on his marks even if there are hundred students this iteration will go through all hundred students so it does not matter whether I found a student mark in the second or third or fourth position so it's a very wasteful algorithm more dangerously it's an algorithm which will get confused if I give that algorithm a role number which does not exist in that set at all this may happen for two reasons firstly my list may have only marks of those who have passed the exam and if my friend that student with this given role is failed there is no way I can find him or her there more importantly I may make a typing mistake while typing the role number so I may have been given a correct role number I may type a wrong role number and that role number may not exist in the entire list of students consequently it is possible that when this particular iteration runs on my computer I will go through from I equal to 0 to n students minus 1 but I will never find a role I equal to given role and I will therefore never make this assignment so when I come out what will happen it will say see out marks for given role are found marks what will happen well I don't think we need to conduct a quiz on this we all know by now that if a variable has not been assigned a value by us the computer will take whatever trash exists in the location that was assigned to the location was allocated to it at the beginning whatever is the value inside that location the computer will truthfully give you that value here is something I would like to add in if such a thing indeed happens so you have given a role number where you have made a typing mistake and then the computer runs through it computer actually does not find it but find some location some contents and print it now suppose that location contains a value minus 25000 this machine will this program will print minus 25000 and I will immediately know that there is an error because nobody will get minus 25000 marks in an exam however suppose the value at that point in time happens to be 57 and the marks are out of 100 and 57 are legitimate past marks then this computer will print 57 and I may actually believe that this given role number has got 57 marks so I may tell his father or whosoever has come to enquire that yes your son has passed he has got 57 marks sadly when the father goes back home and the son enquires in the college the college principal lets him know you have failed your marks do not exist there that is the reason why the program that we or our students write have to be so rigorously checked that such errors must not happen what is the correct way of doing it well I may put a found flag I may set it to zero and if I find a given role I will set not only found marks equal to this but I will say found flag equal to one after I come out I will not output these marks for given role I will say if found flag equal to zero then see out sorry the student has failed else print given marks so that is the kind of precaution that we must take it is possible for me to artificially assign some negative value to found marks before this loop that will also do because I can examine the value of found marks itself if they are greater than equal to zero then I will print them but then there could be an exam which actually awards negative marks well these are all considerations that one must apply while one designs an algorithm I recall a friend of ours who asked the question what is top down approach at the top I think is this generalized thinking identifying various issues in the problem jotting them down would say systematic program design or program writing requires a lot of thinking first in this connection I would like to suggest one good thing to tell your students is that whenever you give them a problem their first impulse is to start writing a program one good advice to give them is for ten minutes or five minutes do not write anything at all don't open your pens just think in your head then spend next ten minutes in jotting down your thoughts on the paper you must not write a single line of code till you have done that what would you jot you jot down the kind of variable name that you may use you jot down the kind of strategies that you will follow you think of what will happen if this is wrong that is not correct you list out all error conditions which you would like to check do this kind of thinking and then and only then start writing your code before beginning our discussions in this session I would like to indicate what I originally started with saying how do I do efficient search why do I need an efficient search I can see that in this particular case even a sequential search like that is rapid fire after all I have read the data you type in the given role number you press the return key believe me even before you raise your head to see what is there on the screen the result would have come because hundred comparisons all hundred values stored in the memory absolutely no problem you will immediately get the result but imagine if there are not hundred but hundred thousand numbers imagine these hundred thousand numbers are in an array not in the computer's main memory but as we shall see later when we discuss the file system they are on the disk wherever they are if you can do a search faster and reduce the number of operations that you do you write a better program so let us look at the algorithmic complexity of this particular approach what is the size of my problem n n is like the n students here so n students may be five ten hundred if I have ten thousand I will declare of course the arrays to be ten thousand or whatever so n is the size of my problem right for the number of operations that are being performed well I have an iteration which goes over n times within each iteration I am making one comparison and in that iteration I am making one assignment if I find that number see even suppose I do not make that assignment or I count it whichever way the maximum number of operations that are happening are n comparisons here so if the size of the problem is n I am doing n comparisons some assignment consequently this algorithm is of order n remember yesterday we talked about an order n square algorithm clearly an order n algorithm is much better however can we do something better for example if let us say the exact expression which converts the execution time into an equation of the kind that we saw where let us say the order n means it is of the type k1 n plus k2 so let us say k1 is equal to 1 and k2 is 0 or negligible that means it takes n operations now somehow if I can find the given element in half of n operation I would have reduced the coefficient significantly from one I would have made it half can I reduce the order what is smaller than n notice that I mentioned earlier once that log n is smaller than n can I do the search of a given number in log n time rather than n time the answer is yes and the answer relates to what we call binary search I am not going to discuss the entire binary search but I would like to spend five minutes in discussing a way which I have found with which people can actually relate to the binary search much more easily there are examples that is normally given is search in the dictionary or search in a newspaper for results where role numbers are ordered in the ascending order in real life our students don't relate to this as binary search they eventually understand it but please note that a student trying to read the meaning of a word from the dictionary will never ever exactly open the dictionary the middle similarly a student trying to read the results from a long pay a large page in which large number of role numbers are given knowing that they are in order the student will actually glance a few numbers at the beginning and will roughly know where his role number should lie if his role number is very high the student will not go to the midpoint but go towards the end of that list the psychology of an individual therefore is not exactly what mathematicians say so we say dictionary search because it is similar to dictionary search but not exactly like that so is there an example which actually can where students can relate that example and say ah this is binary search so I have one example which I picked up from professor Sonny's slides I used it last year it was quite useful I would like to share that with you this example for searching for a given value in the array is I try to show it that it is similar to finding a root by bisection method this is a numerical analysis function of method what it does is that if you have a function we are already familiar with finding out the root so the way we find out the root was earlier by making a initial guess and then making a closer approximation by drawing tangent to the function at respective point the bisection method or midpoint method is completely different it requires two guesses it requires one guess which is on one side of the root and another guess which is on another side of the root so suppose this is the function and let us say this high is one guess and this low is another guess the function value at low is negative the function value at high is positive very obviously it means that if it is a continuous function somewhere it will cross x axis and as we know wherever it crosses x axis that is the root of the equation what does this method do this method does something extremely simple and elegant it identifies high it identifies low now what it does is it finds out an arithmetic mean of the value high and low since low is the x coordinate of this point and high is the x coordinate of this point effectively taking the average of high and low gives you a midpoint of these two and that is the reason it is called bisection method what am I bisecting I am bisecting the range of values from low to high into two parts the method actually most of you know it but I will repeat this for the sake of completeness what you do now is you examine the function value at midpoint in the external case in the example case the value of the function at midpoint is positive the value at high was positive what this means is that the root does not lie to the right of midpoint but it lies to the left of midpoint because we know that at low the function value is negative at mid the function value is positive therefore the root must lie between these two notice that in a single operation we have surgically removed half the space which we were to search imagine that we have to search from low to high I am not examining individual points at this case but that is what I will relate to in case of search at this is the space I am searching in one stroke by taking the midpoint and examining what is the function value I have got rid of half the search space if incidentally the value of the function at midpoint was negative I would have said yes I have to search on this side since it is negative I have to search on this side and what do I do at the search nothing repeat what do I repeat I now said this to high now I have a new high low it is like a new guess I again calculate the midpoint calculate the value if it is positive I have another high or another low please note that the number of steps in which I can compress this space is logarithmic why imagine I had this total space call it one unit after the first hit what is the space half after the second midpoint what is the space left to search one fourth then one earth so the space to be searched is decreasing very very fast and therefore I can reach my conclusion very quickly about the value of the root okay this is the bisection method why do I think that it is a very good example to illustrate to our students to motivate them for the binary search so here is the some redrawing that I have done this of course describes the bisection method incidentally you might want to discuss this as a regular numerical computational example in your class so it says starts with a low and high value such that f of low into f of high is less than one all that it means is that function at high and function at low should have opposite value that is why it should be negative multiplication should be negative otherwise both of the function values at high are positive or negative and that means there may not be any root in between now it says compute the midpoint and compute the function value at midpoint so this is the midpoint and this is the function value at midpoint while function value at midpoint is greater than some small threshold function value locate the next interval to be either low to mid or mid to high so this actually explains the entire iterative logic keep on doing this find a midpoint find out this find out whether it is the new range is low to mid or mid to high and reset mid according then find out whether you have found out that function value is very close to zero that is the meaning of this threshold checking if it is not repeat repeat repeat this is the logic since I can compress my search space and I can reach my root in logarithmic time if I map it onto my problem of doing a search let me first define an equivalent instead of searching a real value which is the midpoint suppose I divide all of this into number of points let us say this is the desired root imagine for a moment that instead of looking at any real value on this I will look at only these discrete points so when I calculate a midpoint I will go to the nearest discrete point so my midpoints are number of points are not infinite as will happen in a real x axis but I am concerning it to be this point but now my logic still works so instead of going to an arbitrary real life I will say these are the number of points I have I will go to the middle point I will evaluate the function is the function positive at midpoint well my my search is still between this mid and this low now I will find out the midpoint of these many points so suppose I had 1000 points to begin with after one iteration I have 500 points to search after next iteration I have 250 points to search I have 125 points to search the my number of searches to be made reduces very rapidly and now I compare that with an array because the number of points on x axis in this illustration can be easily mapped mentally into number of elements in an array which I am searching so either you take the roll number array which had 100 elements and make that roll number array lie flat and compare it with the with the points that you have here you have the similarity what I have done is I have done Ulta I have taken this and and put it like this and now I am saying look my problem was I have this as the 0th element first element roll number one thousand one two three four six eight nine eleven these are the roll and these are my marks instead of searching these roll number serially which would be equivalent of doing a serial search onto these things I now say if these are the points which correspond to an array then just like a bisection search can I not instead of looking at it serially go first limit point examine what is this value consider that I am looking for one thousand two the middle point equivalent to function value is the roll number roll number is one thousand four one thousand four is greater than one thousand two therefore one thousand two is on this side if I am looking for a roll number one thousand ten then I know that one thousand four is smaller than one thousand ten and therefore the roll number is on this side so just like bisection method I am actually partitioning my search space originally I had seven numbers to search now I have three or four on either side so half so every time I reduce the number of elements to be searched into half and therefore the total number of searches I will have to do at most will be equal to log of n if n are the elements and that is how I can reduce the order of my algorithm people were asking as how will you ever change the order this is how I do a completely different thinking and see how can reduce the computations what I had written here is I want you to implement this binary search in more than one ways small changes and then when you ask your students it is useful to give them such a sheet where the data is given here and where they are supposed to hand execute this algorithm to write down in the first iteration what was low what was high what is made in next iteration what is low what is high what is made ask them to implement the same logic this is one implementation ok for example if role made greater than given role role is towards upper half high is equal to mid etc etc people may make small squiggles ask people to solve that problem and execute this algorithm if somebody comes up with two different schemes of binary search they can't vary in principle because binary search is binary search but they may vary in the middle point is not an integer number ok you have for example odd number of points in between that is your range is say from 1 to 8 the average is 8 plus 1 9 divided by 2 average is 4.5 there is no 4.5th element in the arc so you have to consider either fourth element or fifth element sky will not fall is respect of each element you consider because binary search will encompass all other thing any which however this will be small difference one algorithm may take fourth one algorithm may take fifth and depending upon that the actual execution time behavior may slightly change all that I am suggesting is it is worthwhile for you to actually ask students by showing them this slide that once you write your algorithm hand execute this algorithm and write down these values yourself what is the advantage the advantage is that the understanding how my computer program is executing instructions becomes much more clear by this exercise clearly this cannot be done if your array is 10,000 elements but it can certainly be done and I think we should encourage people to do it I myself do this exercise sometimes to ensure that my logic is correct so I think it is a good habit well this is the last thing that I wanted to sort of share with you as a formal example discussions but we still have about 25 minutes so I will now open this for the discussions any any question that you have you may you may please raise it now why time complexity for a for loop is less than that of a for loop I am not sure one can ever make that statement time complexity for for loop has to be very similar to the time complexity of a loop so there is in fact no complexity associated with loop control structure the time complexities of the entire algorithm in Nagpur I can see you Nagpur over to you the benefit of my avu users avu people are able to see that okay the question is can every recursive solution be converted to an iterative one and vice versa frankly I have never examined the possibility of somebody trying to convert an iterative solution into a recursive solution a recursion formula may not be defined for every solution however the answer to first question is yes a recursive solution can always be converted into an iterative solution indeed that is what we always recommend for the sake of efficiency however one must keep in mind that there are situations where the recursive solution is not only illegal but it is extremely simple to specify and code whereas the corresponding iterative solution will become extremely clumsy extremely clumsy a good example of this case so in a nutshell to repeat the answer technically yes I can convert a recursive solution an iterative solution but in practice while I should try and follow iterative solution for the sake of efficiency there are cases when the recursive solution is probably the best solution one such case I think I have briefly mentioned the tower of Hanoi problem you may actually code it as an iterative solution but the solution is extremely clumsy you might want to attempt writing both the recursive part and iterative part there was one more question from VNIT in Nagpur could I have the second question please over to you while I could clearly hear the question I and my other colleagues could not see him because he was hidden behind the madam I would like to go back to VNIT in Nagpur for just one second requesting him to kindly stand up so that all of us can see you over to you yes thank you you are very visible now the question was that whether the memory protection or there was also mention of dynamic allocation first I would like to clarify I don't know where I gave that impression there is no dynamic allocation of memory to arrays that we declare arrays are fixed in size based on whatever size we declare them you can actually cause the actual allocation to be done just at the runtime by doing a hash defined and then doing an array declare dynamic memory allocation happens but it is of a different kind altogether considering not only our character string arrays but even other arrays where we have defined a size if our index value is beyond the prescribed limits from zero to that size then what happens is indeterminate so the correct answer to be given to our students is that if at all I am using an array then it is my responsibility to ensure that in my program I will never use an index expression whose value will be outside the bounds of that are what happens if the array bound is exceeded becomes a question after postpartum it is like saying that these were the rules that were defined somebody did not follow the rule so he died in a road accident and now we are asking how did he die this postpartum is useful but more important is to understand that rule number one is that I must ensure that my index expression does not cross the boundary and this rule must be followed period you can introduce actually some checks so in a nutshell what we tell our students is that look what happens if the bound is exceeded is a different question all together what may happen may be different depending upon different compilers or different systems however as a programmer as a professional programmer you should feel insulted if your program has not taken care of keeping the index value within the declared limits I think that is a harsh answer but that is a good answer there seems to be some confusion about the index expression because earlier also one participant mentioned about dynamic memory allocation or something like that so first of all I would like to make clear that index expression is of course permitted and that is the way in which you access an element index expression evaluation has absolutely nothing to do with determination of the size of the array so index expression I repeat is not related to the size of the array size of the array is fixed once and for all when you declare the array in the statement int float car wherever so if I have said int roll 500 then that array has a maximum size of 500 at any point in time it cannot exceed that period now I come to the index expression when I want to refer to an element inside my program like I was making a comparison is given roll equal to roll I that I is an index expression so the purpose of the index expression is merely to say which particular element at this point in time I am looking at it is in order to determine which particular element the index expression is evaluated so index expression is evaluated every time you make a reference r i r j r 5 in your program you might write it at many places every time you make a reference so I will repeat again such references of nothing to do with array size array size has been fixed at the top once and for all int something 500 int something under that is array size now in my program if given roll equal to roll I that I is an index expression it is in this context I will answer your question your question is suppose the index expression contains two variables floating point is roll x divided by y equal to something where x is float and y is float I will answer this question in two ways first what will actually happen actually happen is very simple if you read my slide carefully it will say it will evaluate the expression and the resulting integer value will be taken to be the index so if x by y is float it will be converted to integer as per the rules of conversion of floating point value to integer value so we don't have to worry about round off round down whatever whatever whatever it does in regular expression evaluation it will do it imagine as if you have that expression instead of writing it inside the square brackets as a reference or index expression you have written it separately in a in an assignment statement and the left hand side was an integer variable so if you have left hand side is equal to some integer equal to whatever expression you write now the expression will result in a floating point number in case you have a floating point division something ultimately the comparable generate instructions to convert this into an integer because it has to be assigned to an integer in the left hand side exactly the same thing will happen here which integer value it will take it will take the same integer value as it would have taken had you done an assignment state so in short why you look at an index expression look at it as if it is a right hand side expression of an assignment state and what will it be replaced by what actual usage whatever would have been the integer value that would have been assigned in that assignment statement that is actually the value so I hope the second question is answered adequately for you let me come back to the first question why why do the references in arrays start with zero and not with one as appears to be natural for us nobody has unfortunately documented this reason but Karnigan and others who define this language in some conversation they have admitted to widely held view which is common sense is the purpose of starting with zero is let me use a diagram to explain it is interesting for people to note this thing we will actually discuss this later but I am just showing it to you suppose this is an array now when we say the array has various elements stored in successive locations internally how are these locations address these are addressed using some numerical values so each location let us imagine we use decimal notation so this location is 1000 this next location is four bytes away because four bytes are allocated let's say you have assigned long end or integer to this so the next location address will be 1004 the next location address will be 1008 the next location address will be 10012 and so on now when the compiler generates the machine language structure what it will have to do is suppose you want to access this element for some operation as indicated by your array reference let us say you have said if you are calling it 1234 then this will be your fourth element in your array as per your terms the way the compiler would generate instructions to calculate this is it will take this base address and it will add a displacement to it such that it points correctly to this how will it calculate the displacement the displacement depends on two things one the difference between the values in addresses in to successive location so this is four bytes second it will depend upon the actual index value suppose it was four and you had a four byte thing it has to add to this thousand four minus one into three because thousand itself is first element second element is four third element is eight fourth element is twelve so this d will not be twelve but only we will have to be twelve and not sixteen I hope you are getting me if it is fourth element then I have to say thousand plus four bytes into four minus one imagine I am referring to let us say eighteenth element I will write it here A 18 for A 18 the address will be one thousand plus eighteenth element one thousand plus eighteen plus four what is this four this is the four bytes multiplied by eighteen minus one that will be the correct address of this location now here is the thing if I start with zero instead of one then this A four will become A three A 18 will become A seventeen and I won't have to do one subtraction which I am doing here in the days that we are talking about 1960s 1970s subtraction addition multiplication division anything that you could save meant a lot so if you have this indexing from zero to something you can take the base address which the compiler has decided to allocate and simply multiply whatever index you have directly by four you don't have to save one subtraction operation which was considered a big thing then people said it may be much easier to have my address indexed from zero to something so as I said I do not know whether this is the true and only reason but this is what I believe what prompted people to take this decision I hope this answers your second question let me go over to JEC Jaipur Cookus I can see you Jaipur Indian College Cookus over to you Gopro sir my question is why we are getting a different time complexity values every time if we are providing the same input to the program over to you sir thank you very much I must first repeat what I said some time ago please stop talking about these times as time complexity so what we are reducing or increasing is not time complexity time complexity of the algorithm is fixed once you write that program what we are doing is we are measuring the actual time required to run the program so let us call it execution time of the program and please do not confuse the execution time of the program with complexity I repeat again once I have written my program no matter where and how I run it and whatever execution time it takes the time complexity of that program is never going to be different because time complexity of the program is determined by the type of instructions that I have written in the program the type of controls I have so I will repeat again what we measure is execution time and let us be consistent we will talk only about execution time now I come to the question a very valid question his question is if he runs the same program many times and if he gives the same input then why does the program execution time differ from different time so once I run it I get say 14.3 seconds another time I run it I get 17.8 seconds third time I run it I get 25 seconds let me confirm that this is the observation over to you please confirm that this is the observation for the first time I just run the program I get the output that is a 13.27 for the same input I get the real time that is about 12.37 so the input is same then why the real time or the user time system is varied my question is this over to you sir exactly what I guessed yes you are very right and I am glad you asked this question because many others would have observed the same thing but they have not resist query his query is that every time he runs a program with the same input once he gets 13.7 seconds another time he gets 12.7 seconds why should it differ at all let me give this and this is a very good question so let me mention this what happens is whenever I am running a program on a computer this is not the only thing that that computer is doing even in case I have a single user machine that is it is a PC and I am sitting alone on that PC the operating system is running behind on that PC and the operating system has maybe 20 30 different small time programs which are running somebody looking at the desk somebody looking at something else whatever whatever there are programs which are automatically initiated for a short spurt by the operating system and that program may suddenly execute once when I am running the program another time it may not execute the situation is worse when I have a central server to which many machines are connected consider this there are 20 users connected to this server I give a command to run a program now this server depending upon how many users are active may allocate less time to me may allocate more time to me consequently my timing will change so and the third point is that that time utility of Unix is not very accurate in fact if you read the documentation it very clearly says that you cannot guarantee accuracy of the time however I if so it less than one second you will not at all be able to major however if there is no other load on the computer and how will you find that out you run you see the number of processes which are running if you list the processes you will find what are the programs that the operating system is running if there are a large number of processes running we cannot automatically find out which are active processes and which are waiting processes but if you have a time difference of a few seconds please learn to ignore it because that does not change your complexity or anything so if you want to test your test bed or test case itself should have a substantial amount of time in general any difference of less than half a minute would not be considered very meaningful and for that difference to be noted the size that you run the size of the problem that you run has to be much larger it is not pertinent in this case but in the conventional benchmarks that we run for large banking applications or something like that it is not uncommon to run a representative workload for something like 8 to 10 hours and then determine what is the average response time or what is the average throughput that you get so thank you very much for asking this question it is a very good question and a very good observation and this is my answer to it thank you so much my colleagues are reminding me that we are already overflowing with in our time schedule we will meet tomorrow morning at 9.30 sharp thank you so much over and out