Pascal _ Chapter 5

download Pascal _ Chapter 5

of 22

Transcript of Pascal _ Chapter 5

  • 8/2/2019 Pascal _ Chapter 5

    1/22

    Chapter 5

    Arrays I

    This chapter covers:

    Declaration of Single Dimension Arrays.

    Searching an array.

    Sorting an array.

    1. Single Dimension Arrays

    In this chapter we will move on to the data structure called an array. The elements in an array must have

    identical types, though these types can be any of the types available in Pascal, even otherarrays. When

    an array has an array for its element type it is called a multi-dimensional array. We will look at these

    later, but first, a look atsingle-dimensional arrays and a closer look at the type RECORD. If you think back

    to the description of the type STRING, you might remember that we used the subscript technique to

    inspect each compartment in the container individually. It might surprise you you learn that the type

    STRING is internally defined as an array, with the type of each compartment declared to be a character.

    Meaning; that a string is an array of type CHAR. Since this is the case, you have already been usingsingle-

    dimension arrays. Unlike a string, though an array can have its declared type consisting of any of the the

    in-built types as well as a user defined type, such as RECORD or an enumerated type.

    To make use of an ARRAY there are two steps:

    It should be declared by an identifier in the TYPE section of the program. This makes it a type.

    Then a request to make one of these new types available to the program must go into the variable

    list.

    1.1. Single dimension arrays, an analogy

    The simplest analogy that I have come up with for a single dimension array is that of a row of books on a

    shelf. In this analogy, the books are numbered from one to fifteen, using subscripts. The spine of a bookcarries two pieces of information the title, and the name of the author. So you could ask the question of

    the program, `What is the ninth book on the shelf'.

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    2/22

    Figure 1 - An array of books

    The storage device has been identified as shelf, the subscript is [9], and the information required is

    title. Since the title is one of two pieces of information carried on the book's spine, it must be a field in a

    RECORD, and we already know about accessing fields in records.

    1.2. Declaring an array

    So, how do we turn this analogy into a data-structure? In the TYPE section of the program:

    Define a CONST for the size of the array.

    Define types for fields in the RECORD for the author's name and the book's title.

    Then define a RECORD containing those types called BOOK.

    CONST

    MAX = 15;

    TYPEAUTHOR_NAME = STRING[20];BOOK_TITLE = STRING[50];

    BOOK = RECORDauthor : AUTHOR_NAME;title : BOOK_TITLE;

    END;

    So now we have this new RECORD type called BOOK, which has two fields, one called author, and the

    othertitle. So now we just need to invent a storage device called a book shelf, to keep our books on.This is added to the TYPE section of the program, which now looks like:

    TYPEAUTHOR_NAME = STRING[20];BOOK_TITLE = STRING[50];

    BOOK = RECORDauthor : AUTHOR_NAME;title : BOOK_TITLE;

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    3/22

    END;

    BOOK_SHELF = ARRAY[1..MAX] OF BOOK;

    This new line reads as: `book_shelf is an ARRAY, from one to fifteen elements, of the type BOOK, that's

    fairly straightforward. Now you need to make a variable of this new TYPEBOOK_SHELF, available to yourprogram, by declaring it in the variable list, so now you have somewhere to store your books, when the

    data is read into the program.

    VARmy_book_shelf : BOOK_SHELF;

    Could that be any simpler? If you remember back to the string example, you will be able to figure out how

    to access an array.

    Name the container by its declared name in the variable list.

    Use the subscript technique to identify the element required.If the elements have the type RECORD, use the fieldname to access the required component.

    Ok, let's get on to this next program using this book shelf analogy. One important point first, is that when

    reading files into an array using a WHILE loop the loop condition must contain two parts. One must refer

    to the end of file (EOF) and the other to the maximum size of the array. This second reference is needed

    in case the file is larger than the number of elements in the array and prevents the program crashing,

    which it would do if the program tried to put a value into an array past its last element.

    Program 1

    PROGRAM book_shelf(INPUT,OUTPUT,booklist);

    { program reads in data from a file and assigns it to an elementin an array, then the user is prompted for a number, and theprogram writes out that element }

    CONSTMAX = 15;

    TYPE

    AUTHOR_NAME = STRING[20];BOOK_TITLE = STRING[50];

    BOOK = RECORDAUTHOR : AUTHOR_NAME;TITLE : BOOK_TITLE;

    END;

    BOOK_SHELF = ARRAY[1..MAX] OF BOOK;

    VARnumber_of_books, { contains the number of books

    loaded into the array }

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    4/22

    number : INTEGER;

    author_in : AUTHOR_NAME;title_in : BOOK_TITLE;

    booklist : TEXT; { data file name }my_book_shelf : BOOK_SHELF;

    BEGINnumber_of_books := 0;WRITELN;RESET(booklist); { reset file for reading }WHILE (number_of_books

  • 8/2/2019 Pascal _ Chapter 5

    5/22

    This FOR loop can be put in the program anywhere once the initial reading in from the file is done and the

    number of occupied elements is assigned to number_of_books.

    Now we have constructed the data-structure, which is what ourBOOK_SHELF is, we can now go on to the

    next stage, getting the power out of an array by searching for a value.

    2. Operations On Arrays

    2.1. Searching for a value

    A slight modification to the program book_shelf would allow us to search through the array ~for a

    value, in this case we could search for either the author or the title. The element of a data structure for

    which we search, is called the key field. In this case the key fieldwill be the author. In the above

    program the subscript identifiernumber was used to write out the element of an array. We used a counter

    variable I to control a loop. When searching through an array we need a value to search for as well as a

    loop counter. First of all we read in the value we wish to search for, then inspect the first element of the

    array to see if it matches this value, using the loop counter as the subscript. If this value doesn't match,we increment the loop counter by one, and inspect the next element. In the simplest form, this requires a

    fragment of code like this below. The variable number_of_data_items contains the number ofarray

    elements which contain data, and is similar to number_of_books in the previous program.

    WRITE('Enter the name to search for : ');READLN(the_name);

    I := 1;WHILE (the_name the_array[I].name) AND (I

  • 8/2/2019 Pascal _ Chapter 5

    6/22

    so only ifI is less than MAX will the value ofI be written out. This can easily be used to write out the

    other fields of the record, because you know that the value ofI points to the array elementwhich

    contains the searched for value. Searching through arrays almost always causes problems for the beginner

    programmer, because they find difficulty in dealing with the first element and the last element of the

    array, what happens most is that the program tries to access an element past the end of the array as will

    occur when the loop counter becomes equal to MAX + 1. This causes a run-time error and the programcrashes without explaining very clearly why. Normally it is best to search through an array using a WHILE

    loop, because the program can exit from the search as soon as a matching value is found. In the next

    program I use a FOR loop because I want to search right through the entire array. This is because in a

    library data-base search, you would want to write out all titles by the author, not just the first one to be

    found. This next program is just a modified version of the one above. It uses the same data file to read in

    the data, and the same datastructure to store it. The assignment statements are a little different, in this

    example the read in data is assigneddirectly to thefieldin the array, without the use ofdummy variables

    which hold the data values temporarily. As I said before, if you need to use apostrophes in your text, you

    need to put in two of them together as in the line from the next program:

    WRITE('Please enter authors name : ');

    Program 2

    PROGRAM book_shelf_two(INPUT,OUTPUT,booklist);

    { this program is a library catalogue, it asks forthe name of an author, then lists all titles bythat author }

    CONSTMAX = 15;

    TYPE

    AUTHOR_NAME = STRING[20];BOOK_TITLE = STRING[50];

    BOOK = RECORDauthor : AUTHOR_NAME;title : BOOK_TITLE;

    END;

    BOOK_SHELF = ARRAY[1..MAX] OF BOOK;

    VARI, { loop counter }number_of_books,number : INTEGER;

    booklist : TEXT; { file name }my_book_shelf : BOOK_SHELF;an_author : AUTHOR_NAME;found : boolean;

    BEGINnumber_of_books := 0;WRITELN;RESET(booklist); { reset file for reading }

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    7/22

    WHILE (number_of_books

  • 8/2/2019 Pascal _ Chapter 5

    8/22

    MAX = 20; { all the elements need not be filled }

    TYPEA_PHONE_NUMBER = STRING[10];A_NAME = STRING[20];

    AN_ADDRESS = STRING[50];

    DETAILS = RECORDphone_number : A_PHONE_NUMBER;name : A_NAME;address : AN_ADDRESS;

    END;

    PHONE_BOOK = ARRAY[1..MAX] OF DETAILS;

    VARnumber_of_entries,I : INTEGER;area_phone_book : PHONE_BOOK;found : BOOLEAN;

    customer_number : A_PHONE_NUMBER;

    phone_book_file : TEXT;

    BEGINI := 1;

    found := FALSE;RESET(phone_book_file);WHILE (I

  • 8/2/2019 Pascal _ Chapter 5

    9/22

    BEGINWRITE('There is no entry for ');WRITELN(customer_number);

    END;END. { program phone_book }

    You will have noticed again that there are no assignment statements as such in the file reading section of

    the program. The method used to load the array is by directly reading the values into their correct fields

    in one line. The first WHILE loop, is the one used to do this. The use of the with, means that the line,

    READLN(phone_book_file,area_phone_book[I].phone_number);

    is eliminated, and replaced by the line:

    READLN(phone_book_file,phone_number);

    But they both do the same thing, that is read the next data item from the file, and place it into theappropriate field of the array ~element, that the current value ofI indicates. The file required by the

    above program should be of the form:

    123456John Smith42 Hill St, Dunblane654321Henry Alexander21 Braeside, Alva

    .

    .

    .837462

    Peter WoodRiverview Dr, Edinburgh284574Jim Iggnatowski1 Dinnet Row, Portree

    There is no need to have exactly the same number of entries in a file as there are elements in the array. In

    fact you need not have more than three or four, just enough to test it with. In order to test the program,

    you could directly assign values to the fields of the array, and leave the file handling to later.

    To assign values into these fields would require code similar to,

    WITH area_phone_book[1] DOBEGIN

    phone_number := '123456';name := 'John Smith';address := '42 Hill St, Dunblane';

    END;

    You can of course repeat this for any element number in the array.

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    10/22

    2.2. Linear search times

    The main problem with the two search algorithms above is the fact that, no matter what, they may search

    through the entire array, without finding a value. If you change the value ofMAX in program five, to

    200,000, and at the prompt enter a number you know is not in the file, you will get a search time of

    around fifty-five seconds, this is what is called the not in array time. That is how long the program runs

    before it reports to the user that the searched for value does not exist in the supplied data. So the problem

    exists therefore, that both these search algorithms must search through the entire array before coming to

    that conclusion. Imagine therefore, that if we could put the data into an array in order so that astring

    beginning with 'A' came before one beginning with 'Z', and ones beginning with an 'a' came before one

    beginning with a 'z'. The if we were searching using a WHILE loop for the string value 'Steinbeck', the exit

    condition could include a statement to the effect that if the key fieldhad an ASCII value greater that the

    searched for string. Then the possible position for that string had been passed, and therefore the value did

    not exist in the array. To continue with the search would be pointless, and so exit from the loop, and

    report the not found result. Because each character has its own unique ASCII value it is possible to

    compare strings in the same way as numbers are compared to each other.

    For example:

    Apple is less than Banana.

    Smith is greater than Jones.

    100 is less that 200.

    12345 is less than 43214.

    So how do we arrange to have these ordered arrays in Pascal? Well, after the data is stored into the array

    we must first use a sorting algorithm, before we perform the search algorithm.

    2.3. Sorting an array

    The main objective of sorting an array is to reduce the not in array time of a linear search, a linear

    search is when the algorithm starts searching from one end and inspects each element, before going on to

    inspect the very next element. The averagefound in array time remains the same whether the array is

    sorted or not. As long as the values are properly distributed. I mean by this if you only search through an

    array for a low value and all the low values are bunched up at either end, then the found in array time

    will be small or large, but if all the values are fairly well spread out then the averagefound in array time

    for the entire range of values will will be roughly the same. The first sorting algorithm we will look at is

    called selection sort. As we already know, in order to search through a data-structure such as a string or

    an array we need a loop. Inselection sort, we actually need two loops. We always know the size of thearray, and we should always know the number ofelements which have been loaded with a value. So a

    FOR loop would seem to fit the bill, since we will want to examine every single element of the array. In

    the initial condition ofselection sort, the first FOR loop's control variable is set at 1, and the second FOR

    loop's control variable is set to that same value plus 1.

    2.4. Selection sort, algorithm

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    11/22

    In this code fragment, assume that: I, J, and temp are declared as type INTEGER, MAX, is a CONST equal to

    ten, the size therefore of the arraytest_array.

    FOR I := 1 TO number_of_loaded_elements DO

    { set J to start at the element ahead of I }FOR J := (I+1) TO number_of_loaded_elements DO

    IF test_array[J] < test_array[I] THENBEGIN { swap }

    temp := test_array[J];test_array[J] := test_array[I];test_array[I] := temp;

    END; { swap }

    Believe it or not, that is all the code required to sort through an array of any size.

    The initial condition of the array can be seen below

    Figure 2 - Sorting arrays : Before sorting

    The first step in selection sort is to compare the values in the elements indicated by the subscript

    values of both I, and J. If the value in test_array[J] is not less than the value in test_array[I] then

    the counterJ is incremented by one, while the value ofI remains at one.

    The control variable J, is incremented until the value in test_array[J] is less than the value in

    test_array[I], this brings us to the performance of the first swapping action, see below.

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    12/22

    Figure 3 - Sorting : Step 1

    Once a value is found in test_array[J] to be less than that value in test_array[I], the first swap can

    occur. There are three steps in this operation.

    The swap algorithm:

    Copy the contents oftest_array[J] into the temp variable.

    Copy the contents oftest_array[I] into test_array[J].

    Copy the contents oftemp into test_array[I].

    Note:- The type oftemp must be the same as the elements of the array. If the array is of the type

    INTEGER, then temp must be an INTEGER, but if its type is a record structure then temp must also be arecord structure. The result of the first swap is shown below.

    Figure 4 - Sorting : Step 2

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    13/22

    The counterI is still equal to one, while the counterJ is again incremented until the value in

    test_array[J] is found to be less than that in test_array[I]. This next occurs when J = 6, and the

    value in test_array[J] is two - see below.

    Figure 5 - Sorting : Step 3

    The result of the this swap is shown below.

    Figure 6 - Sorting : Step 4

    By now you can see that the value contained in test_array[I] is the lowest value in the whole array,

    but J continues to be incremented until it reaches the termination value of the for loop, namely when J =

    10, in this case.

    The sorting algorithm then increments I to two, in the outerFOR loop and the whole cycle starts over.

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    14/22

    Figure 7 - Sorting : Step 5

    Note:- Before the second FOR loop is entered each time, the counterI is set first, then the counterJ takes

    that value plus one, so that J will always be just in front ofI at the beginning of each cycle. After this

    sorting, there is a drastic reduction of the not in array time search time, since the search can be stopped

    when the position where the searched for value should be, is passed. For instance, if you were searching a

    library database for the author name 'Fitzgerald', and you had reached the element which contained

    'Hemingway', then you know, because the array is sorted, that there is no possibility of an entry for

    'Fitzgerald' being further on in the array so you can stop the search. The next program uses this example

    andsort algorithm, and steps through the sorting process, on the screen.

    Program 4

    program sort_array(input,output);

    { this program, uses the selection sort algorithmto sort the array right before your eyes.The use of double digits such as 04, 08 is forscreen formatting purposes only }

    CONSTMAX = 15;

    TYPEINTEGER_ARRAY = ARRAY[1..MAX] OF INTEGER;

    VARI,J,K,swaps, { holds the number of swaps done }temp,number_of_loaded_elements : INTEGER;

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    15/22

    test_array : INTEGER_ARRAY;

    BEGINtest_array[1] := 04; test_array[2] := 07;

    test_array[3] := 09; test_array[4] := 03;test_array[5] := 15; test_array[6] := 02;

    test_array[7] := 08; test_array[8] := 05;test_array[9] := 12; test_array[10] := 18;

    number_of_loaded_elements := 10;

    WRITELN(' *** Initial Condition ***');WRITELN;WRITELN('+---+---+---+---+---+---+---+---+---+---+');

    FOR I := 1 TO number_of_loaded_elements DOWRITE('|',test_array[I]:2,' ');

    WRITELN('|');

    WRITELN('+---+---+---+---+---+---+---+---+---+---+');

    FOR I := 1 TO number_of_loaded_elements DO{ set J to start at the element ahead of I }FOR J := (I+1) TO number_of_loaded_elements DO

    IF test_array[J] < test_array[I] THENBEGIN

    swaps := swaps+1;temp := test_array[J];

    test_array[J] := test_array[I];test_array[I] := temp;

    WRITE('Press to continue : ');READLN;

    WRITELN;

    WRITE(' * * Condition After ');WRITELN(swaps:0,' swaps * *');WRITELN('+---+---+---+---+---+---+---+---+---+---+');

    { write out the contents of the array }FOR K := 1 TO number_of_loaded_elements DO

    WRITE('|',test_array[K]:2,' ');

    WRITE('|');WRITELN(' When I = ',I:0,', and J = ',J:0);WRITELN('+---+---+---+---+---+---+---+---+---+---+');

    END;WRITELN;WRITELN(' * Sorting Complete *');

    WRITELN;END. { program sort_array }

    Now you can sort an array you can add this algorithm before a search algorithm in any program, and so

    reduce the not in array time.

    Some examples of average search times, through a 200,000 element array, assuming a random

    distribution of values:

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    16/22

    The not in array time

    Unsorted linear search: 55-60 seconds average.

    Sorted linear search: 25-30, roughly half.

    I suppose you can see a huge improvement in the time it takes the program to report to the user or to the

    program that the searched for data item is not in the array. This is important, because sorted or unsorted,

    in an array with a normal distribution of values, thefound in array time is roughly the same, because

    sometimes the search will have to run all the way to the end of the array, and sometimes the value will be

    found at the beginning of the array.

    2.5. The binary chop search algorithm

    You have seen how we can reduce the not in array time fairly drastically, by sorting an array. By using

    the binary chop algorithm, to search a sorted array we can cut that time even further. The whole conceptof this algorithm is to eliminate half of an array from the search at each step, until the required element is

    either found or not found. The consequence of this is that both the not in array time, and thefound in

    array time will be roughly the same, and will be reduced to a tiny amount compared with a

    straightforward linear search on either a sorted or an unsorted array. To use the binary chop algorithm,

    the array must be sorted unlike with the linear search algorithm, where sorting has no effect on either of

    the times. In this algorithm, assume found to be declared as a boolean, and mid_point, top_end, and

    bottom_end to be type INTEGER. Also MAX is a CONST equal to ten, and searched_for_value to be of the

    same type as the arrayelements.

    found := FALSE;top_end := number_of_loaded_elements;mid_point := 0; { arbitrarily initialise to zero }

    bottom_end := 1;

    WHILE (NOT found) AND (bottom_end

  • 8/2/2019 Pascal _ Chapter 5

    17/22

    Figure 8 - Binary-chop : Initial condition

    Now we enter the WHILE loop, and perform the first calculation.

    mid_point := (top_end + bottom_end) DIV 2;

    This will yield

    mid_point := (10+1) DIV 2;

    therefore

    mid_point := 5;

    The integer division operator discards anything after the decimal point. Even if that part is .9999 it will

    not round up.

    bottom_end := (mid_point + 1);

    therefore

    bottom_end := 6;

    The condition after the first loop is shown below.

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    18/22

    Figure 9 - Binary-chop : After first loop

    In the next loop,

    mid_point := (6 + 10) DIV 2;

    therefore

    mid_point := 8;

    and then ELSE condition in Line 3 becomes true and so,

    top_end := (8 - 1);

    therefore

    top_end := 7;

    The condition after the second loop is shown below.

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    19/22

    Figure 10 - Binary-chop : After second loop

    In the next loop,

    mid_point := (7 + 6) DIV 2;

    therefore

    mid_point := 6;

    and then the ELSE - IF condition in line 2 becomes true and so

    bottom_end := (6 + 1);

    therefore

    bottom_end := 7;

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    20/22

    Figure 11 - Binary-chop : After third loop

    In the next loop,

    mid_point := (7 + 7) DIV 2;

    therefore

    mid_point := 7;

    Now line 1 becomes true, and so the BOOLEANfound becomes TRUE, and the variable mid_point yields

    the position of the searched for value.

    Figure 12 - Binary-chop : After fourth loop

    l : Chapter 5 23-04-20

  • 8/2/2019 Pascal _ Chapter 5

    21/22

    I promised you that this would operate a search, quite a bit faster than a simple linear search, and so the

    next program will demonstrate this. Since this is just a demonstration program I have used a FOR loop to

    load the array the benefit of this is that it is already in order. So the search can run without waiting for the

    array to being sorted.

    Program 5

    PROGRAM binary_chop(INPUT,OUTPUT);

    { a demonstration program, which searches through

    an integer array using the binary chop algorithm }

    CONSTMAX = 200000;

    TYPEINTEGER_ARRAY = ARRAY[1..MAX] OF INTEGER;

    VAR

    found : BOOLEAN;I, { for loop counter }top_end,mid_point,bottom_end : INTEGER; { array counters }

    test_array : INTEGER_ARRAY;searched_for_value : INTEGER;

    BEGIN{ load up array with in-order integers }FOR I := 1 TO MAX DO

    test_array[I] := I;

    WRITE('Enter value you wish to search for : ');READLN(searched_for_value);

    found := FALSE;top_end := MAX;bottom_end := 1;

    WHILE (NOT found) AND (bottom_end

  • 8/2/2019 Pascal _ Chapter 5

    22/22

    IF found THENBEGIN

    WRITE('The value searched for is in');WRITELN(' element ',mid_point:0);

    END

    ELSEWRITELN('Value Not Found');

    END. { program binary_chop }

    When you run this program, you will find that the not in array time and thefound in array time is the

    same.

    2.6. Binary chop search times

    If you are interested this time is about 0.005 seconds. The maximum time taken by the binary chop

    algorithm is arrived at with the formula:

    (time taken to inspect single element) * log2 (number of elements in array)

    55

    * 17.6096 = 0.005 seconds-------------

    200,000

    Copyright 2004 Joseph S. Dorward

    l : Chapter 5 23-04-20