Pascal _ Chapter 5
-
Upload
jose-gomes -
Category
Documents
-
view
215 -
download
0
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