CHAPTER 9

ARRAYS

Suppose I wish to keep scores of all my students in the computer. In some classes I have one hundred students, in others I have thirty students. If I need to keep names of all one hundred students in the computer's memory, I will have to have names for all these memory locations. Imagine declaring all these variables; not only it is very time consuming, it takes a lot of memory space to store the program itself. It would be much better to set aside a group of memory locations and call it by a single name. This what happens when we declare an array.

If we declare an array of 20 elements of integers, Pascal will set aside enough memory to hold 20 integers. Since an integer occupies two bytes in most PC's we know that it would require 40 bytes. Pascal needs to know where the beginning memory location is, and which element we are manipulating. For example, if we need to place an integer as the fifth element, Pascal needs to place that integer in the ninth and tenth memory locations from the beginning. Suppose the beginning address is 100. To calculate where an element should be stored, multiply the length of the variable by the position-1 and add it to the base address. The third element would be stored at (3-1)*2 + 100, or 104. The twentieth integer would be stored at (20-1)*2 + 100 or 138.

MEMORY ELEMENT

LOC

1. 100 first element

2. 101

3. 102 second element

4. 103

5. 104 third element

6. 105

7. 106 fourth element

8. 107

9. 108 fifth element

10. 109

Fortunately, we programmers do not have to keep track of this- the Pascal compiler does. We merely need to indicate what type and how many elements would make up the array.

example:

type

allStudents = array[1..100] of string[25];

var

Student : allStudents;

In order to understand how the array is declared, you need to have some background in user defined data types. (This is discussed in Appendix 9A. Make sure to review it before proceeding.) In the above example, for the variable 'Student', 100 elements of 25 byte each would be set aside by Pascal, coming to a total of 2500 bytes. A program using an array is given in Program 9-1.

 

 

PROGRAM 9-1

Program ArrayEx (input,output,namefile);

{This program accepts a series of Names and holds these names

in an array. These names are then written to a file.}

type

ArrayType = array [1..30] of string[25];

var

names : arraytype; {global variables}

count : integer;

{*******************************************************}

Procedure readNames(var names:arrayType; var count:integer);

begin

count := 1;

write('Enter Name (or type QUIT): ');

readln(names[count]); {read first name}

while (names[count] <> 'QUIT') do

begin

count := count +1;

write('Enter another name (or type QUIT): ');

readln(names[count]);

end;

count := count -1; {do not count 'QUIT', so remove it}

end;

{******************************************************}

Procedure writeNames(var names:arrayType; var count:integer);

var

i : integer;

nameFile : text;

begin

assign(nameFile,'names.dta'); {relate to DOS file}

rewrite(nameFile); {Open file to write}

for i:= 1 to count do

writeln(nameFile,names[i]); {write to file}

close(nameFile);

writeln('Names written to file are:');

for i:= 1 to count do

writeln(names[i]);

end;

{********************************************}

begin

readnames(names,count);

writenames(names,count);

end.

Program run:

Enter Name (or type QUIT): JODY

Enter another name (or type QUIT): BILLY

Enter another name (or type QUIT): REGGIE

Enter another name (or type QUIT): MARY

Enter another name (or type QUIT): ADAM

Enter another name (or type QUIT): BECKY

Enter another name (or type QUIT): CAROL

Enter another name (or type QUIT): CARL

Enter another name (or type QUIT): JIM

Enter another name (or type QUIT): DON

Enter another name (or type QUIT): DORA

Enter another name (or type QUIT): TIM

Enter another name (or type QUIT): TONY

Enter another name (or type QUIT): JANE

Enter another name (or type QUIT): JERRY

Enter another name (or type QUIT): JACK

Enter another name (or type QUIT): QUIT

If you were to type the file out using the DOS type command, you will see the following:

B:\>TYPE NAMES.DTA

JODY

BILLY

REGGIE

MARY

ADAM

BECKY

CAROL

CARL

JIM

DON

DORA

TIM

TONY

JANE

JERRY

JACK

B:\>

Program 9-1 has two procedures, one to read all the names into an array, the other to write the names out to a file and to the screen. Two parameters are passed to these procedures, names and count. Each individual array element is read using the following statement:

readln(Names[1]); readln(names[2]); readln(names[3]); etc.

In the program I replaced the numbers 1, 2, 3, etc. with the variable 'count'. Writing is also done the same way:

writeln(Names[1]); writeln(names[2]); etc.

The numbers in brackets were replaced by a variable 'i' which is incremented by the for loop.

Now suppose you have twenty students and want to assign a project to five of these students. You could find a random number between one and twenty and print that name as follows:

i := random(20)+1;

writeln (names(i));

Do this five times and you will have five names. The only problem with this approach is that a number could be repeated when generating random numbers, so the same student could be picked more than once. To avoid this you may need to keep track of who has been called using a Boolean array. Declare an array of Boolean also having 20 elements. Initialize all of them as false to indicate that they have not been picked. When a student is picked do the following:

i := random(20)+1

while (picked(i) = false) then

begin

writeln(names(i));

picked(i) := true;

end;

It would be best for me to illustrate with a complete program. Let us write a program that will read the file of names you created in Program 9-1 and will pick five students randomly without repeating a picked name.

The idea is to first read all the names into an array, keeping track of how many names are read. Now create another array of boolean and set them all to false to indicate no names have been picked yet. Now pick a name randomly and see if it has been picked; if it has not been picked before, then print it and increment a counter. We need to keep this counter going so that we can stop after successfully picking five names. If the name has been picked before, get another name randomly.

PROGRAM 9-2

Program ArrayEx2 (input,output,namefile);

{This program reads a series of Names from a file

and holds these names in an array. Five names are

then picked from this list.}

type

ArrayType = array [1..30] of string[25];

var

names : arraytype; {global variables}

count : integer;

{*******************************************************}

Procedure readNames(var names:arrayType; var count:integer);

var

nameFile : text; {used for text files}

begin

assign(nameFile,'names.dta');

{in Pascal known as nameFile; in DOS known as names.dta}

reset(nameFile); {open to read from it}

count := 0; {count is used to keep track of how many read}

while not eof(nameFile) do

begin

count := count +1;

readln(nameFile,names[count]); {read from file}

end;

close(nameFile);

end;

 

PROGRAM 9-2 CONTINUED.

{********************************************}

Procedure PickNames(names:arrayType; count:integer);

var

i, randomNumber : integer;

picked : array[1..30] of boolean;

begin

for i:= 1 to count do

picked[i] := false; {all names are set to not picked}

i := 0;

randomize;

repeat

randomNumber := random(count)+1;

while not(picked[randomNumber]) do

begin

writeln(names[randomNumber]);

picked[randomNumber] := true;

i := i+1;

end; {while}

until i >= 5; {for}

end; {PickNames}

{************************************************}

begin {main}

readnames(names,count);

picknames(names,count);

end.

Program run:

B:\>EXIT

REGGIE

JERRY

ADAM

DON

BILLY

Type EXIT to return to Turbo Pascal...

Microsoft(R) MS-DOS(R) Version 5.00

(C)Copyright Microsoft Corp 1981-1991.

B:\>

Please make a note of an important concept in this program. We did not pick a name randomly, we just picked a position. We checked to see if that position was picked before. The same principle can be used to shuffle a deck of cards. We can first assign names of cards to an array of 52 elements. Now we just shuffle the 52 numbers, or the positions. Once the numbers are shuffled, we can print the names out in the shuffled order.

Here is another example using arrays. If you do not know any thing about the calculation of a standard deviation, just read through this section. In order to do a standard deviation we do the following:

1. read a series of N numbers into an array.

2. add all these numbers.

3. find the mean, divide the sum by N.

4. find the difference between the mean and each number.

4a. find the square of that difference.

5. add all the squared differences.

6. Divide the sum of squared differences by N-1.

7. Find the square root.

 

PROGRAM 9-3

Program arrayEx3(input, output);

type

arraytype = array [1..31] of integer;

var

dailyvalue : arraytype;

sum, average, deviation, devsquared,

sumsquared, variance, sd : real;

count, howmany : integer;

begin

sum:=0; sumsquared:=0;

write ('How many values for standard deviation? ');

readln (howmany);

writeln ('ENTER EACH VALUE FOLLOWED BY RETURN:');

for count := 1 to howmany do

begin

readln(dailyvalue[count]); {READ VALUES INTO ARRAY}

sum:=sum+dailyvalue[count];

end; {for count}

average:= sum/howmany; {FIND AVERAGE}

for count:= 1 to howmany do

begin

deviation := average-dailyvalue[count];

devsquared:= deviation * deviation;

sumsquared:=sumsquared + devsquared;

end;

variance:=sumsquared/(howmany-1);

sd := sqrt(variance);

{*********************** print results ***************}

writeln ('VALUES ENTERED ARE: ');

for count:= 1 to howmany do

write (dailyvalue[count]:5);

writeln; {this writeln to add a carriage return}

writeln ('STD DEVIATION = ',sd:5:2);

end.

 

Program run:

How many values for standard deviation? 6

ENTER EACH VALUE FOLLOWED BY RETURN:

82

99

89

50

88

87

VALUES ENTERED ARE:

82 99 89 50 88 87

STD DEVIATION = 16.86

Type EXIT to return to Turbo Pascal...

Microsoft(R) MS-DOS(R) Version 5.00

(C)Copyright Microsoft Corp 1981-1991.

B:\>

Suppose you are taking the pulse rate on yourself every day. You want to find the standard deviation of that. This is accomplished using three for loops. You will read all daily values into an array. While each value is being read you could keep a running total. This is accomplished in the first for loop. When finished reading, find the average.

A second for loop is set up to find the sum-squared. Then find the standard deviation. The third loop is used to print all the values stored in the array, and to print the results. If the statistics used here were a little difficult, don't worry. But you do need to understand the concept of the arrays.

MULTIDIMENSIONAL ARRAYS

An array of an array is called a two dimensional array. it would be like a table with rows and columns. Suppose the table is called Tax_Table then the fourth row fifth column of that table would be referred to as Tax_Table(4,5). Multiple arrays of an array, or multiple arrays of multiple arrays are known as multidimensional arrays.

Suppose you were assigned to make a 4 year activity book for a Presidential term of four years. You will need to have an array of four years of 52 weeks each. Each week then will have array of seven days. Each day you will record one major event that happened that day. Let us write array definition for this.

 

Program 9-4 uses a multidimensional array to handle 20 students each in four sections of four classes. This program is very time consuming to run, you will have type in 32 names.

PROGRAM 9-4

Program MultiDim (input, output);

{This program demonstrates the use of multidimensional

arrays. A three dimensional array is used here. Suppose four courses in computer science are offered in the first Summer term, each course having four sections of twenty students.

The program is designed to hold names of the students in

a multidimensional array of 4 x 4 x 20, a total of 320 names.

Since it is rather difficult to type in all these names,

I have assigned "vacant" to all slots. Then to demonstrate

how to read into a multidimensional array, I have asked to

input two students each for each section, a total of 32

names. Then the entire array is printed. You should see

two slots of each section occupied with names and the

rest vacant.}

 

type

students = array[1..20] of string[15];

sections = array[1..4] of students;

Classes = array[1..4] of Sections;

var

Name :Classes;

student,section,class: integer;

begin

{Assign all slots to Vacant}

for Class := 1 to 4 do

for section := 1 to 4 do

for student:= 1 to 20 do

Name[Class,Section,Student]:='Vacant';

 

{Now Register two students each for each section,

just for example}

For class := 1 to 4 do

for section :=1 to 4 do

for Student := 1 to 2 do

begin

write('Enter a student name for Class ');

writeln(class:5,' Section ',section:3);

readln(Name[Class,Section,Student]);

end;

{Let's see what we got}

for class := 1 to 4 do

begin

writeln('Class = ',Class:4);writeln;

for Section :=1 to 4 do

begin

writeln(Class:4,' Section = ',Section:2);

for student:= 1 to 20 do

writeln(Name[Class,Section,Student]);

writeln;

end;

writeln;

end;

end.

 

 

 

Partial program run:

(only two names are entered for each section)

C:\TP>

Enter a student name for Class 1 Section 1

LINDA GASTEL

Enter a student name for Class 1 Section 1

ELI OCHOA

Enter a student name for Class 1 Section 2

GAIL ALSUP

Enter a student name for Class 1 Section 2

MARCOS HERNANDEZ

Enter a student name for Class 1 Section 3

DIANA PENA

Enter a student name for Class 1 Section 3

ADELA VALDEZ

Enter a student name for Class 1 Section 4

AIDA APONZE

Enter a student name for Class 1 Section 4

LILIA MUNOZ

Enter a student name for Class 2 Section 1

GIL SAENZ

Enter a student name for Class 2 Section 1

RICARDO GOMEZ

Enter a student name for Class 2 Section 2

DAVID SALAZAR

Enter a student name for Class 2 Section 2

JAIME CORDERO

Enter a student name for Class 2 Section 3

After entering all the names, the program will output all names for each section and class, if not complete, will print EMPTY for the vacant slots.

 

APPENDIX 9A

ENUMERATED AND SUBRANGE DATA TYPES

Thus far all data types used in our programs were standard data types provided by Pascal. Pascal allows programmers to define their own data types. Suppose we want to define a new data type called MyFamily. MyFamily will be composed of members, just like the integer data type is composed of individual members. In order to define such a data type you will have to list (enumerate) all members of that type. Example:

Type MyFamily = (Joe, Jim, James, Mary, Kathy);

Once you have defined a new data type, you can declare variables of this type. A variable can assume any value from the enumerated list. Example:

Var Child : MyFamily;

In this example, 'child' can only have a value of either, Joe, Jim, James, Mary, or Kathy. There is one main difference between enumerated data types and standard data types; you cannot read or write variables of enumerated data types.

Readln(Child); This would be illegal.

Writeln(Child); This would be illegal.

Child := Jim; This is legal;

If child1 < Child2 then writeln('message'); This is legal.

for child := Joe to Kathy do This is legal.

Once a data type has been declared, you can make subrange data types. Since the integer data type is already defined by Pascal, you can define a subrange data type of scores having integers 1 to 100. Example:

scores = 1..100;

Since myFamily was enumerated by the programmer, a subrange data type can be defined as follows:

brothers = Joe..James;

Pascal automatically assigns ordinal position values to each of the enumerated members starting from zero. In the example of MyFamily, ordinal values would be assigned as follows:

ordinal value

Joe 0

Jim 1

James 2

Mary 3

Kathy 4

Let us write a program using this new information we learned. Program 9-5 will list members of my family, first the boys and then the girls.

PROGRAM 9-5

end. 

Program run:

Here are the children of Abraham family:

Son #1 Philip.

Son #2 Matthew.

Son #3 John.

Son #4 Sam.

Daughter #1 Kunju.

Daughter #2 Mary.

Type EXIT to return to Turbo Pascal...

Microsoft(R) MS-DOS(R) Version 5.00

(C)Copyright Microsoft Corp 1981-1991.

C:\TP>

PROGRAM EXPLANATION

The program heading clearly shows this program only has output, no input. The next section defines new data types. All members of MyFamily are enumerated. Data type 'boys' and 'girls' contain a portion each of 'MyFamily'. Therefore, these are called sub-range data types.

The next section is the variable declaration section. Two variables are declared, son and daughter. We only use one variable, son; the other variable, daughter is declared for illustration only and not used in the program.

A for-loop is set up where 'son' will have value ranging from Philip to Sam. The case statement checks for the value of 'son' and appropriate action is taken. In each case the name of the 'son' is printed and the ordinal position of the value is printed as well. Notice, we add a one to the ordinal value, this is because Pascal assigns a zero to the first value; however, we want the first value to be one.

After all the sons are listed, daughters are listed. Since there are only two girls, there is no need for a loop. Notice that the girls ordinal positions are printed after subtracting 3 (minus number of boys plus one to adjust for beginning position, -4 + 1 = 3).

ASSIGNMENTS FOR CHAPTER 9

1. Write a program to take a deck of cards and cut it exactly at the 26th card, place the bottom half on top of the other half. Now print out the original deck of cards and the cut deck of cards. Use three or four characters to name each card.

2. Write a program to shuffle a deck of cards and print out the original deck of cards and the shuffled deck.

3. Write a program to ask for a month in numbers (1 to 12) and to print out the name of that month. Make sure to use an array to do this.

4. Write a program to count the occurrences of vowels in a sentence and print out how many times each vowel occurred. Make sure to use an array of characters for the sentence.

5. Program 9-6 creates a Tic-Tac-Toe board and allows two individuals to play. However, the program as it is written, does not allow the last move. Modify the program so that it will accept nine moves, instead of eight.

PROGRAM 9-6

Program TicTacToe (input, output);

uses crt;

type

ticType = array[1..3,1..3] of char;

var

tic : ticType;

row, column,i,play : integer;

won : boolean;

Procedure checkwin(var won: boolean);

begin

{check if won}

for row := 1 to 3 do

if (tic[row,1] = 'X') and (tic[row,2] = 'X') and (tic[row,3]='X') then won:=true;

for column := 1 to 3 do

if (tic[1,column] = 'X') and (tic[2,column]='X') and (tic[3,column]='X') then won := true;

if (tic[1,1] ='X') and (tic[2,2] = 'X') and (tic[3,3] ='X') then won := true;

if (tic[1,3] ='X') and (tic[2,2] = 'X') and (tic[3,1]='X') then won := true;

if won then writeln('Player One has won the game!'); if won then exit;

 

for row := 1 to 3 do

if (tic[row,1] = 'O') and (tic[row,2] = 'O') and (tic[row,3]='O') then won:=true;

for column := 1 to 3 do

if (tic[1,column] = 'O') and (tic[2,column]='O') and (tic[3,column]='O') then won := true;

if (tic[1,1] ='O') and (tic[2,2] = 'O') and (tic[3,3] ='O') then won := true;

if (tic[1,3] ='O') and (tic[2,2] = 'O') and (tic[3,1]='O') then won := true;

if won then writeln('Player Two has won the game!');

end;

 

TicTacToe game continued..

procedure printTic (tic:ticType) ;

begin

writeln(' ', 1:4, 2:4, 3:4);

for row:= 1 to 3 do begin

writeln('--------------------');

write(row:3);

for column := 1 to 3 do

write (' | ',tic[row,column]);

writeln;

end;

end;

begin

{*************** initialize and show board ************}

for row:= 1 to 3 do

for column:= 1 to 3 do

tic[row,column]:= ' ';

printtic (tic);

{***************** begin playing ****************}

i := 1;

won := False;

while (i < 9) and not(won) do

begin

for play := 1 to 2 do

begin

write ('Player ',play:2,' Please Play (choose row, column)');

readln (row, column);

while (tic[row,column] <> ' ') or (row >3) or (column >3)

do begin

write('Illegal move, try again! ');readln(row, column);

end;

if play = 1 then tic[row,column] := 'X'

else tic[row,column] := 'O';

printtic(tic);

i:=i+1;

checkwin(won); if won then exit;

end;

end;

 

 

Last part of the program run:

Player 1 Please Play (choose row, column)3 3

1 2 3

--------------------

1 | X | O | X

--------------------

2 | X | O |

--------------------

3 | O | | X

Player 2 Please Play (choose row, column)3 2

1 2 3

--------------------

1 | X | O | X

--------------------

2 | X | O |

--------------------

3 | O | O | X

Player Two has won the game!

Type EXIT to return to Turbo Pascal...

Microsoft(R) MS-DOS(R) Version 5.00

(C)Copyright Microsoft Corp 1981-1991.

C:\TP>