(For codeYourLife) week 4
7 Arrays: Lists and Tables
Although the value of a variable may change during execution of a program, in all our programs so far, a single value has been associated with each variable name at any given time. In this chapter, we will discuss the concept of an array—a collection of variables of the same type and referenced by the same name. We will discuss one-dimensional arrays (lists) and two-dimensional arrays (tables). You will learn how to set up and use arrays to accomplish various tasks.
After reading this chapter, you will be able to do the following:
· Declare and use one-dimensional arrays
· Manipulate parallel arrays
· Understand the relationship in programming between databases and parallel arrays
· Represent character strings as arrays
· Use the Length_Of() function to validate data in character arrays
· Declare and use two-dimensional arrays
· Combine one- and two-dimensional parallel arrays in a program
In the Everyday World Organize It with Lists and Tables
Chances are that you frequently use lists in your daily life. The following is a common example:
Shopping List
1. Milk
2. Bread
3. Eggs
4. Butter
Or if you’ve ever done a home improvement project, you might have developed a list such as the following:
Tools Required List
1. Hammer
2. Saw
3. Screwdriver
If you write individual items on separate random pieces of paper, you might get them confused and end up going to the grocery store for a saw. By presenting a convenient method of organizing and separating your data, a list prevents this from happening.
Sometimes a single list isn’t powerful enough for a given purpose. In this case, we use a table—a collection of related lists—such as the following:
Phone Book
· A. Name List B. Address List C. Phone List
· 1. Ellen Cole 1. 341 Totem Dr. 1. 212-555-2368
· 2. Kim Lee 2. 96 Elm Dr. 2. 212-555-0982
· 3. Jose Rios 3. 1412 Main St. 3. 212-555-1212
Notice that this table contains three separate (vertical) lists that are all related horizontally. For example, to call someone you would scan down the Name List for the appropriate name, then look across that line to the Phone List to find the corresponding phone number. Could anything be more convenient? Thanks to a little organization and structure; you can easily find what you’re looking for, even if the individual lists are hundreds of items long.
Everyone from farmers (weather tables) to accountants (ledgers) to sports fans (player statistics) uses lists and tables. If you use a spreadsheet program, you’re using an electronic table and if you write a computer program with a lot of data that “goes together,” you might organize it as a list or a table called anarray. Often, programs that use data from databases store that data in arrays in order to manipulate and process it.
7.1 One-Dimensional Arrays
A one-dimensional array is a list of related data of the same type (for example, integers or strings) referred to by a single variable name with an index number to identify each item. In this section, we will discuss how to set up and manipulate these arrays, and we will present several advantages of their use.
Array Basics
Since an array stores many data values under the same variable name, we must have some way to refer to the individual elements contained within it. Eachelement is an item in the array and has its own value. To indicate a particular element, programming languages follow the array name by an index numberenclosed in parentheses or brackets. For example, if the name of an array is Month and the index number is 3, the corresponding array element might be indicated by Month[3] .
The name of the array is similar to the name of a variable. For example, we might have an array called Scores that contains the final exam scores for a certain class of 25 students. Therefore, the array would have 25 scores. Each score is an element, and the array must indicate which particular element the program refers to at any time. This is done by using the index number. The first element of an array in most programming languages is referred to with the index number 0, although some may use 1 as the first index value. An array with 25 elements will have index numbers that range from 0 to 24. The first index value is a significant fact to keep in mind, especially when you manipulate arrays with loops. In our pseudocode, we follow the more common practice of starting array indexes with 0.
An individual element of an array is referred to by writing the array name followed by its index number surrounded by brackets. For example, since the first element of an array has index number 0, the first element of the array Scores would be referred to as Scores[0], and in that same array the second element is Scores[1]and the third is Scores[2]. We read these as "Scores sub 0", "Scores sub 1", and "Scores sub 2". Here, 0, 1, and 2 are called the subscripts—or index numbers—of the array elements.
An array element such as Scores[2] is treated by the program as a single (or simple) variable and may be used in input, assignment, and output statements in the usual way. Thus, to display the value of the third student’s final exam score, we use the following statement:
Write Scores[2]
Example 7.1 shows how to enter elements in an array.
Example 7.1 Entering Elements in an Array
If we wanted to input the final exam scores of a class of 25 students using an array named Scores, which has 25 elements, we could use a loop as follows:
For (K = 0; K < 25; K++)
Write "Enter score: "
Input Scores[K]
End For
What Happened?
· On the first pass through the loop, the input prompt is displayed ("Enter score: ") and the Input statement pauses execution, allowing the user to enter the first test score. Because K = 0, this value is then assigned to the first element of the array Scores, which is Scores[0].
· On the second pass through the loop, K = 1 and the next value input is assigned to Scores[1], the second element of Scores.
· On the third pass through the loop, the value input is assigned to Scores[2].
· Because this loop began with K = 0, we only need to go to K = 24 to complete all 25 passes through the loop and load all 25 values.
After 25 passes through this little loop, all the scores have been entered. This is certainly a more efficient way to write code than to type 25 Write and Inputstatements for 25 different variables! We will see that using arrays not only makes it much easier to load large amounts of data but also makes manipulating that data easier and more efficient.
Declaring Arrays
Arrays are stored in a computer’s memory in a sequence of consecutive storage locations. As you know, when you declare a variable the computer sets aside a small amount of memory to store the value of that variable. The data type of the variable, the name of the variable, and the value of the variable are one little package and that package is stored in a small amount of memory. When you create an array, you tell the computer what the data type is and how many elements the array will contain. Then a space in the computer’s memory is set aside for that array. If an array has five elements, the computer will set aside space with five equal parts, one part for each element of the array. Therefore, each element of the array has the same sized space in computer memory, the same array name, and the same data type. And all the elements are stored in consecutive locations in memory. The index (or subscript) number of the element sets it apart from the other members in the array.
Declaring Arrays in C++, Visual Basic, and JavaScript
While not always necessary, it is a good idea to inform the program, prior to the first use of an array, how many storage locations to set aside (or allocate) for that array. The array declaration statement can include the array name and the size of the memory space needed for that array. In program code, this is done by declaring the array in a statement at the beginning of the program or program module in which it is used. It is also possible to declare arrays without specifying the size, and this is used in some cases where the programmer may want the size of the array to be open ended. The declaration statement varies from language to language. The following shows how an array named Age, consisting of a maximum of six integer values, would be declared in three popular languages:
· In C++, the following statement:
int Age[6];
allocates six locations referred to as Age[0], Age[1], . . . , Age[5].
· In Visual Basic, the following statement:
Dim Age(6) As Integer
allocates six locations referred to as Age(0), Age(1), . . . , Age(5).
· In JavaScript, the following statement:
var Age = new Array(6);
allocates six locations referred to as Age[0], Age[1], . . . , Age[5].
In JavaScript the data type of the array will be determined when its elements are assigned values. However, all the elements of a JavaScript array must still be of the same data type.
Notice that the arrays begin with the subscript 0, and therefore, end with a subscript that is one less than the number of elements in the array.
In this book , for an array of integers, we will use the following pseudocode:
Declare Age[6] As Integer
to allocate six locations referred to as Age[0], Age[1], . . . , Age[5]. In memory, this array would occupy six consecutive storage locations, and assuming that the elements have been assigned the values 5, 10, 15, 20, 25, and 30, the array can be pictured as follows:
|
Address |
Age[0] |
Age[1] |
Age[2] |
Age[3] |
Age[4] |
Age[5] |
|
Contents |
5 |
10 |
15 |
20 |
25 |
30 |
It would have been possible to create six integer variables with the values 5, 10, 15, 20, 25, and 30. We could have named them Age5, Age10, Age15, and so forth. But there are many advantages associated with using arrays. Arrays make it easy to manipulate many variables at a time, using only a few lines of code. Example 7.2 shows the declaration and use of an array.
Example 7.2 When It Rains, It Pours, So Use an Array 1
1 Before attempting to implement the examples in this chapter with RAPTOR, be sure to read the information in the Running With RAPTOR section ( Section 7.6 ) on how RAPTOR creates and initializes arrays.
This program uses arrays to find the average monthly rainfall in Sunshine City for the year 2014, after the user has entered the rainfall for each month. First the program computes the average of the monthly rainfall for a year and then displays a list of the months, identified by number (January is month 1, February ismonth 2, and so forth), each month’s rainfall, and the year’s average monthly rainfall. In the program, we will show all the variable declarations needed, not just those for the arrays.
1 Declare Rain[12] As Float
2 Declare Sum As Float
3 Declare Average As Float
4 Declare K As Integer
5 Set Sum = 0
6 For (K = 0; K < 12; K++)
7 Write "Enter rainfall for month " + (K + 1)
8 Input Rain[K]
9 Set Sum = Sum + Rain[K]
10 End For
11 Set Average = Sum/12
12 For (K = 0; K < 12; K++)
13 Write "Rainfall for month " + (K + 1) + " is " + Rain[K]
14 End For
15 Write "The average monthly rainfall is " + Average
What Happened?
· Line 1 declares an array named Rain, which will consist of 12 elements of type Float.
· Lines 2 and 3 declare two floating point variables, Sum and Average. The initial value of Sum is set to 0 on line 5.
· Line 4 declares one integer variable, K. This variable will serve as a counter and will also identify each month when we write the display later.
· Lines 6–10 include the first For loop, where the user inputs the 12 rainfall figures (one for each month) into the array Rain. The loop also totals the value of the rainfall amounts for 12 months. At this point, note the following:
· The variable K has been initialized to 0 and is set to count to 11. This will result in 12 passes through the loop, which is what we need to load values for 12 months in a year. Since we want to associate each element of the Rain array with its corresponding value of K, we begin the loop with K = 0.
· However, the first month of the year is month 1, which is why the Write statement on line 7 asks the user to "Enter rainfall for month " + (K + 1). On the first pass, the Write statement asks for month 1 and on the 12th pass, the Write statement asks for month 12.
· Line 8 gets the input and stores the value. On the first pass, the user inputs a value for Month 1 since K + 1 = 1 and the value is stored in Rain[0] since K= 0. On the next pass, the user inputs a value for month 2 since K + 1 is now 2, but the value is stored in the second element of the Rain array, which isRain[K] or Rain[1]. On the last pass, the user enters a value for month 12, which is stored in Rain[11].
· Line 11 computes the average value of monthly rainfall amounts for the whole year.
· At this point, the computer has stored rainfall amounts as 12 variables, but all the variables are elements of the array named Rain. The computer also knows the average of the yearly rainfall. All that is left is to tell us the results.
· The second For loop on lines 12–14 displays the month (K + 1) and the amount of rainfall for that month, which was stored in Rain[K] on line 8. This line is pretty important; when we say Write Rain[K], it’s the same as saying Write the value stored in element K of the Rain array.
· Line 15 writes the average of the rainfall for all the months.
If you need to be further convinced about the advantages of using arrays to manipulate a large amount of related data, try to rewrite the pseudocode shown in Example 7.2 without an array. Instead of an array named Rain, declare 12 variables (January, February, March, April, May, June,July, August, September, October, November, and December) for the values of each month’s rainfall amounts. Then rewrite the pseudocode to display each month, its rainfall amount, and the average for the year.
In Example 7.2 , the variable we used as a counter to load the array and to identify the number of the month we were referring to at any time wasK. Initially, we set the value of K to 0, which meant that there were certain conditions that had to be met. We could not refer to the month as simplyK. Instead we had to use K + 1 since there is no month 0. We also were required to set the test condition so that the loop ends when K = 11 to ensure 12 passes. However, we could also have written this program segment with the initial value of K = 1. If you rewrite this pseudocode with K = 1, what changes will you need to make so that the program does the exact same thing as shown in Example 7.2 ? This is the first Self Check question of this section.
The following program segments show how C++, Java, and JavaScript code is implemented to load the Rain array, display its contents, and calculate and display the average of all entries. For clarity, in all code samples the variable names have been kept exactly the same as the pseudocode.
Before we move on we will use Example 7.2 to illustrate how the monthly rainfall pseudocode would look in three programming languages.
The subscript or index value of an array element can be defined as a number, a variable, or any expression that evaluates to an integer. For example, if an array isnamed Food and a variable named Num has the value of 5, all of the following will assign "cake" to the 6th element of Food:
· Food[5] = "cake"
· Food[Num] = "cake"
· Food[10 – Num] = "cake"
When It Rains . . . with C++
The C++ code for Example 7.2 is as follows:
1 int main()
2 {
3 float Sum; float Average;
4 float Rain[12];
5 int K;
6 Sum = 0; Average = 0;
7 for (K = 0; K < 12; K++)
8 {
9 cout << "Enter rainfall for month " << (K + 1) << end1;
10 cin >> Rain[K];
11 Sum = Sum + Rain[K];
12 }
13 Average = Sum/12;
14 for (K = 0; K < 12; K++)
15 {
16 cout << "Rainfall for month " << (K + 1) << " is " ↵ << Rain[K] << end1;
17 }
18 cout << "The average monthly rainfall is " << Average << end1;
19 return 0;
20 }
When It Rains . . . with Java
The Java code for Example 7.2 is as follows:
1 public static void main(String args[])
2 {
3 float Sum; float Average;
4 Rain[] = new float[12];
5 int K;
6 Scanner scanner = new Scanner(System.in);
7 Sum = 0; Average = 0;
8 for (K = 0; K < 12; K++)
9 {
10 System.out.println("Enter rainfall for month" + (K + 1);
11 Rain[K] = scanner.nextFloat();
12 Sum = (Sum + Rain[K]);
13 }
14 Average = Sum/12;
15 for (K = 0; K < 12; K++)
16 {
17 System.out.println("Rainfall for month" + (K + 1) + ↵ " is " + Rain[K]);
18 }
19 System.out.println("The average monthly rainfall is " ↵ + Average);
20 }
When It Rains . . . with JavaScript
The JavaScript code for Example 7.2 is as follows:
1 <html> <head>
2 <title>Rainfall</title>
3 <script type="text/javascript">
4 function raining()
5 {
6 var Sum = 0; var Average = 0; var K;
7 var Rain = new Array(12);
8 for (K = 0; K < 12; K++)
9 {
10 Rain[K] = parseFloat(prompt("Enter rainfall for month "));
11 Sum = Sum + Rain[K];
12 }
13 Average = Sum/12;
14 for (K = 0; K < 12; K++)
15 {
16 document.write("Rainfall for month " + (K + 1) + " is " + Rain[K] + "<br />");
17 }
18 document.write("The average monthly rainfall is " + Average);
19 }
20 </script> </head>
21 <body>
22 <input type = "button" value = "click to begin" onclick = "raining()" />
23 </body></html>
There are a few noteworthy points:
· Most of the syntax for the actual logic of the program is identical for all the languages. The main differences are in how the languages handle starting a program and how they retrieve and display data. In C++, the statement int main() begins the program, while in Java, the program begins with public static void main(String args[]), and in JavaScript the main function, called raining() in this example, is accessed from a button on the web page (see line 22).
· In C++, the cout and cin statements allow for input and output. In Java, an object, called a scanner object is created. It allows input to be placed into a buffer. The item in parentheses (in this case, System.in) tells the computer where the input is coming from (the keyboard in this case). For example:
System.out.println("Enter rainfall for month" + (K + 1));
tells the computer to output what is inside the parentheses. The use of println does the same thing as endl in C++—it tells the computer to move to the next line after executing this line of code. Then the line:
Rain[K] = scanner.nextFloat();
tells the computer to look at the scanner object, get the next floating point data that is in the buffer and store it in Rain[K].
In JavaScript, the prompt statements get input from the user and store what the user enters in the variable or array element on the left side of the statement. In JavaScript, everything entered by a user is initially stored as text so the prompt is enclosed within the parseFloat() method. This changes the user’s input from text to floating point data. The prompt appears as a small window on a web page screen with a box for user input. Thus, the line:
Rain[K] = parseFloat(prompt("Enter rainfall for month "));
prompts the user for a value, converts the value to a number, and stores it in Rain[K]. Output is created with the document.write() statements. Whatever is inside the parentheses will be displayed on the web page. The <br /> tag is an indicator to move to the next line on the display.
Self Check for Section 7.1
For Self Check Questions 7.1 and 7.2 refer to Example 7.2 .
1. 7.1 Rewrite the pseudocode to load the array, Rain, with 12 rainfall amounts using K = 1 as the initial value of K.
2. 7.2 Rewrite the pseudocode of Example 7.2 using While loops instead of For loops.
In Self Check Questions 7.3 and 7.4, what is displayed when code corresponding to the given pseudocode is executed?
3. 7.3
4. Declare A[12] As Integer
5. Declare K As Integer
6. Set A[2] = 10
7. Set K = 1
8. While K <= 3
9. Set A[2 * K + 2] = K
10. Write A[2 * K]
11. Set K = K + 1
End While
12. 7.4 In this exercise, Letter is an array of characters and the characters that have been input are F, R, O, D, O.
13. Declare Letter[5] As Character
14. Declare J As Integer
15. For (J = 0; J <= 4; J++)
16. Input Letter[J]
17. End For
18. For (J = 0; J <= 4; J+2)
19. Write Letter[J]
End For
20. 7.5 The following program segment is supposed to find the average of the numbers input. It contains one error. Find and correct it.
21. Declare Avg[10] As Integer
22. Declare Sum, K As Integer
23. Set Sum = 0
24. For (K = 0; K <= 9; K++)
25. Input X[K]
26. Set Sum = Sum + X[K]
27. End For
Set Average = Sum/10
28. 7.6 State two advantages of using arrays instead of a collection of simple (unsubscripted) variables.
7.2 Parallel Arrays
In programming, we often use parallel arrays. These are arrays of the same size in which elements with the same subscript are related. For example, suppose we wanted to modify the program of Example 7.2 to find the average monthly rainfall and snowfall. If we store the snowfall figures for each month in an array named Snow, then Rain and Snow would be parallel arrays. For each K, Rain[K] and Snow[K] would refer to the same month so they are related data items. Example 7.3 illustrates this idea further.
Example 7.3 You’ll Be Sold on Parallel Arrays
This program segment inputs the names of salespersons and their total sales for a given month into two parallel arrays (Names and Sales) and determines which salesperson has the greatest sales (Max). Figure 7.1 shows the flowchart for this pseudocode. It’s helpful to walk through the flowchart to visualize the logic used to solve this problem. The pseudocode assumes that Max, K, and Index have been previously declared as Integer variables.
Pseudocode
1 Declare Names[100] As String
2 Declare Sales[100] As Float
3 Set Max = 0
4 Set K = 0
5 Write "Enter a salesperson's name and monthly sales."
6 Write "Enter *, 0 when done."
7 Input Names[K]
8 Input Sales[K]
9 While Names[K] != "*"
10 If Sales[K] > Max Then
11 Set Index = K
12 Set Max = Sales[Index]
13 End If
14 Set K = K + 1
15 Write "Enter name and sales (enter *, 0 when done)."
16 Input Names[K]
17 Input Sales[K]
18 End While
19 Write "Maximum sales for the month: " + Max
20 Write "Salesperson: " + Names[Index]
What Happened?
· In this program segment, we do not use a For loop to input the data because the number of salespersons may vary from run to run. Instead, we use a sentinel-controlled loop with an asterisk (*) and a 0 as the sentinels. The user indicates that there are no more salespeople to enter by entering the asterisk (*) for the name and 0 for the amount.
Figure 7.1
Flowchart for Example 7.3
· Lines 1 and 2 declare two arrays. Names is an array of String elements and Sales is an array of Floats. You may wonder why these arrays have been declared to have 100 elements each, when the program is going to allow the user to enter as many salespeople as necessary. In some programming languages, you may have to specify the size of the array. It’s better to declare an array for a larger number of elements than you plan to use. In this program segment, the maximum number of salespeople that can be entered is 100, but we assume that is plenty. If there are only 38 salespeople, the rest of the elements of the array are simply unused.
· Let’s look at what happens on lines 5–8 in more detail. Line 5 requests the input (a salesperson’s name and his/her monthly sales amount). Line 6 explains to the user how to finish entering data. Lines 7 and 8 are of some special interest. When a user enters a name and an amount, the first value entered is stored in the Names array and the second value entered is stored in the Sales array. This is very important! The information must be entered in the correct order. Imagine that the fifth entry was for a saleswoman named Josephine Jones whose sales totaled $4,283.51. If the information was entered in the wrong order,Names[4] would store 4283.51. This would not be the correct name, but a computer doesn’t care what text is entered into a string so a string of numbers would be a legitimate entry. However, when the user entered “Jones” into the Float array, Sales, at best the program would simply halt or give an error message or, worse, it would crash.
· Line 9 begins the loop to do the work of this program. It continues until the asterisk is entered.
· Line 10 checks to see if the value of the current salesperson’s monthly sales is greater than the maximum value to that point (Max). The variable Max holds the maximum value, so that as the entries are made, Max will continually change every time an entry has a larger sales amount.
· Line 11 sets the variable named Index equal to the value of K. K is just an integer. If the value in Sales[K] is greater than the Max value, we want the newMax value to be the value of whatever Sales[K] is at this point in the program. Let’s say for example, that Sales[3] is the high value at one point in the program. We need a way to associate that value with the salesperson who sold that amount. The variable Index keeps track of that. Regardless of what the value of K becomes as the program proceeds, until there is a higher value for Sales[K], the person associated with Names[Index] (in this case, Names[3]) remains the high seller.
· In line 12, if the current salesperson has sold more than whatever value was in Max, the new Max is set equal to sales amount of the current salesperson. If the current salesperson has not sold more than the value of Max, nothing changes.
· Lines 14–17 increment the counter and get another set of data. The loop continues until the user ends it by entering the two sentinel values.
· Line 18 simply ends the While loop and lines 19 and 20 display the results.
In Example 7.3 , what would happen if a salesperson had sold nothing for that month? The values entered would be the salesperson’s name for theName array and 0 for the Sales array. Would this create a problem? No, because the test condition tests only for the salesperson’s name. As long as the salesperson who sold nothing was not named "*", the program would continue.
And what would happen if the user decided to end the input by entering "*" for the Name array but 23 instead of 0 for the Sales array? Would the program end? Yes, it would because the test condition on line 9 (Names[K] != "*") would no longer be true, the While loop would not execute, and the value 23 would not be compared with other values.
You may be wondering why we ask the user to enter a 0 for the sales amount if the program segment is only interested in the salesperson’s name. When this program is coded and run, there are two inputs required for each entry. The user must enter something for the sales amount. We could just easily have specified "Enter *, −8,983 when done" on lines 6 and 15, but we picked 0 since it makes sense that a normal monthly sales figure wouldn’t be nothing. However, we have to specify some number since Sales is an array of numbers.
Avoiding Errors
There is a small problem with the program in Example 7.3 . If the user enters "*" at the first Input statement (line 7), the While loop is never entered. Then the variable Index on line 20 is undefined. Can you think of a way to rectify this problem?
One possible solution would be to initialize Index to an impossible value, like −1, before the loop begins. If the loop is entered, the value of Index is changed to K. But if the loop is never entered, Index retains its initial value. Then before the final display, a selection statement could check the value of Index. If it is still −1, the output might say something like “No names were entered." and a program crash would be avoided.
Some Advantages of Using Arrays
There are many advantages to using arrays and even more advantages to using parallel arrays. As you have already seen, arrays can reduce the number of variable names needed in a program because we can use a single array instead of a collection of simple variables to store related data. Also arrays can help create more efficient programs. Once data are entered into an array, that data can be processed many times without having to be input again.
Example 7.4 illustrates this point.
Example 7.4 Arrays Save You Time and Effort
Professor Merlin has asked you to help him. He has 100 students in his four classes but he is not sure that all of them took his last exam. He wants to average the grades for his last exam in four sections of his medieval literature course and then determine how many students scored above the average. Without arrays you would have to enter all the test scores, find their average, and then enter them again to determine how many exceed the average. But you know how to use arrays, so you won’t need to enter the input a second time. The following pseudocode does the job. We assume that the variables have been declared as given:
· Integer variables: Sum, Count1, Count2, and K
· Float variables: Score and Average
1 Declare Medieval[100] As Float
2 Set Sum = 0
3 Set Count1 = 0
4 Write "Enter a test score (or 999 to quit): "
5 Input Score
6 While Score != 999
7 Set Medieval[Count1] = Score
8 Set Count1 = Count1 + 1
9 Set Sum = Sum + Score
10 Write "Enter another score or 999 to quit: "
11 Input Score
12 End While
13 Set Average = Sum/Count1
14 Set Count2 = 0
15 Set K = 0
16 While K < Count1
17 If Medieval[K] > Average Then
18 Set Count2 = Count2 + 1
19 End If
20 Set K = K + 1
21 End While
22 Write "The average is:" + Average
23 Write "The number of scores above the average is: " + Count2
What Happened?
In the first While loop, which inputs the scores, the Count1 variable serves as a subscript for the array Medieval and also counts the number of scores input. Since we don’t know exactly how many students took the exam, we must use a sentinel-controlled loop here. However, when it’s time to determine the number of items above the average (Count2), we know the number of items that have been input. A second While loop is used (lines 16–21) with a limit value of one less than Count1 to determine the number of scores above the average.
Let’s think about this limit value for a moment. The value of Count1 on line 12, at the end of the While loop, is equal to the number of scores entered. For example, since Count1 is initialized to 0 on line 3, each time Professor Merlin enters a score for a student, Count1 has the value of 1 less than the number of students up to that time. This is done so that the value of the first score will be stored in Medieval[0]. However, Count1 is incremented on the line following the score input (line 8). Therefore, when all the scores have been entered and the While loop is exited, Count1 will have the same value as the number of scores that have been entered. For example, if the Professor has 23 students in a class, he will store those students’ scores in Medieval[0] through Medieval[22]but, on exiting the While loop, Count1 will equal 23.
The While loop that begins on line 16 needs to compare each score (each element of the Medieval array) with the value of Average. Therefore, if there are 23 scores entered in Medieval[0] through Medieval[22], the loop must make 23 passes. The counter for this loop, K, begins at 0 and, since it increments by 1for each pass, by the time K has reached 22, it will have completed 23 passes. This is why we set the limit condition of this loop on line 16 to K < Count1.
Another benefit of using arrays is that they help create programs that can be used with greater generality. If we use 30 simple variables to hold the values for 30 test scores, we can only have 30 test scores. If five students register late for a class and we need variables for 35 students, we have to declare five more variables. However, because we do not have to use all the elements that were allocated to an array when it was declared, arrays give us more flexibility, as shown in Example 7.5 . We could initialize an array for scores with space for 50 elements, even if we only use 30, or later in the semester, use 35. The unused spaces in the computer’s memory are set aside for a value, if one is entered.
Example 7.5 Arrays Make Programming Easy and Concise
Professor Merlin received a list of all his students from the head of his department. The names are listed in alphabetical order from A to Z. But Professor Merlin is not a forward-thinking professor. He likes his student class list to appear in reverse alphabetical order from Z to A. He asks you to write a program to allow him to input a list of names and display them in reverse alphabetical order. This is easy to do using arrays, even if the number of names to be input is unknown at the time the program is written.
1 Declare Names[100] As String
2 Set Count = 0
3 Write "Enter a name. (Enter * to quit.)"
4 Input TempName
5 While TempName != "*"
6 Set Names[Count] = TempName
7 Set Count = Count + 1
8 Write "Enter a name. (Enter * to quit.)"
9 Input TempName
10 End While
11 Set K = Count − 1
12 While K >= 0
13 Write Names[K]
14 Set K − K − 1
15 End While
What Happened?
This program segment inputs the list of names into the array Names and then displays the elements of that array in reverse order by “stepping backward” through a While loop whose control variable (K) is also the array subscript. The purpose of the variable TempName is to hold the string entered by the user temporarily. If that string is really a name and not the sentinel value "*", the first While loop is entered and the string is assigned to the next array element.
Note that when the first While loop ends, the value of Count is one greater than the highest subscript of the Names array. This is why we begin the secondWhile loop with the new counter, K, set equal to the value of Count − 1.
A Word About Databases
Nowadays, virtually all companies and organizations store enormous amounts of data in databases. Databases consist of many tables that are linked in many ways. As we have seen, a table can contain lists of related data; in other words, a table is a group of parallel lists. The information in the tables can be retrieved and processed for a large variety of purposes.
How Databases May Be Used
Imagine a database used by a company that provides and sells online computer games. The company might have one or more tables that store information about people who play each game. If this imaginary company offers fifteen games—say, five word games, five adventure games, and five brain teaser games—the owners might want to do some market research. While each table relating to one game might include players’ information, such as the player’s name, username, age, contact information, dates played, scores, and so on, the market research might only be interested in some of this data. The owners might want to identify which age groups gravitate to which types of games or if scores are a factor in deciding which players keep returning to a certain game. By performing what is called a query, the owner can get this information quickly from the database.
Using the same tables in the database, the company’s market research team can compile many types of information. Queries can discover which games are played most often on weekends, during daytime hours, how many players of what ages, gender, or even location are most likely to play which types of games and much more.
The company can also, using the information in the database, offer users of the site options to view statistics of other players or even find ways to get players to work together.
How Do Arrays Fit In?
The data retrieved from databases is processed and displayed through computer programs. When these programs are written, often the required information from the tables is temporarily stored in parallel arrays. It is manipulated, processed, and the results are output not directly from the database but from the arrays in the programs that are written by programmers. Therefore, while it is important to understand how to get and use information to load arrays directly from a user, understanding how to use arrays has a much more far-reaching purpose. Working with arrays is central to virtually all computer applications in today’s world.
Self Check for Section 7.2
1. 7.7 Write a program segment that inputs 20 numbers in increasing order and displays them in reverse order.
2. 7.8 Redo Example 7.2 so that a user will enter values for both snowfall and rainfall for each month using parallel arrays, Rain and Snow.
3. 7.9 Add to the program you created in Self Check Question 7.8 so that the display shows corresponding values for snowfall and rainfall for each month. Before displaying the averages for snowfall and rainfall, each output line should look like this:
month X: Snowfall: Snow[X −1], Rainfall: Rain[X − 1]
4. 7.10 Give two examples of situations where parallel arrays would be useful.
5. 7.11 True or False: An array of names and an array of numbers cannot be parallel because they are of different data types.
6. 7.12 Imagine you are starting your own small business selling widgets that you create in your home workshop. You want to keep track of your customers in a database. List the information you might store in a table about customers.
7. 7.13 Add to the imaginary database you created in Self Check Question 7.12 by listing information you might want to store in a table about your inventory.
7.3 Strings as Arrays of Characters
In the first section of this chapter, we described one-dimensional arrays and some ways to use them. In this section, we will discuss how arrays are related to the topic of character strings.
In Chapter 1 , we introduced character strings (or more simply, strings) as one of the basic data types. Some programming languages do not contain a string data type. In those languages, strings are implemented as arrays whose elements are characters. Even in programming languages that contain this data type, strings can be formed as arrays of characters. In this section, we will consider strings from this point of view. If you have been using the RAPTOR sections of this text you will recall how we used the RAPTOR indexing property to access specified characters in a string of text. When indexing is used, a string is processed as an array of characters in the manner that will be described in this section.
When defining a string as an array of characters in our pseudocode, we will always indicate the data type in the Declare statement. This practice is normally required when writing actual code. For example, the following statements
Declare FirstName[15] As Character
Declare LastName[20] As Character
define the variables FirstName and LastName to be strings of at most 15 and 20 characters, respectively.
Concatenation Revisited
Whether we consider strings as a built-in data type or as arrays of characters, we can perform certain basic operations on them, as shown in Example 7.6 .
Example 7.6 Stringing Arrays Together
This program segment inputs two strings from the user, concatenates them, and displays the result. You will recall that concatenation means to join two items, and the + symbol is used to perform the concatenation operation.
Declare String1[25] As Character
Declare String2[25] As Character
Declare String3[50] As Character
Write "Enter two character strings. "
Input String1
Input String2
Set String3 = String1 + String2
Write String3
In this pseudocode, notice that String1, String2, and String3 are defined as arrays of characters, but when they are used in the program, the array brackets do not appear. For example, we write
Input String1
Input String2
rather than
Input String1[25]
Input String2[25]
This usage is typical of actual programming languages and also conforms to our previous way of referencing strings when they were considered as a built-in data type.
After the two strings have been input, the statement
Set String3 = String1 + String2
concatenates them and the Write statement displays the result. If code corresponding to this pseudocode is run and the user enters the strings "Part" and "Time" for String1 and String2, the program’s output would be as follows:
PartTime
Concatenation versus Addition
The use of the concatenation operator in the following line of Example 7.6
Set String3 = String1 + String2
merits a short comment at this point.
If, for example, a person had three Integer variables as follows:
Var1 = 10, Var2 = 15, Var3 = 0
the statement:
Set Var3 = Var1 + Var2
would result in Var3 = 25.
However, if Var1, Var2, and Var3 were String variables with values as follows:
Var1 = "10", Var2 = "15", Var3 = "0"
the statement
Set Var3 = Var1 + Var2
would result in Var3 = "1015"
In our pseudocode, as well as in most programming languages that use the same symbol for concatenation as for addition, it is the data type declaration that tells the computer which operation (addition or concatenation) to perform.
In a language like JavaScript (or RAPTOR), you must use parentheses to ensure that the computer knows when the + sign indicates addition. The following JavaScript code snippet will demonstrate this:
function concatenation()
{
var Var1 = 24;
var Var2 = 12;
document.write("Var1 concatenated with Var2 is: " + Var1 + ↵ Var2 + "<br />");
document.write("Var1 added to Var2 is: " + (Var1 + Var2));
}
The output from this program would be:
Var1 concatenated with Var2 is: 2412
Var1 added to Var2 is: 36
String Length versus Array Size
The length of a string is the number of characters it contains. For example, the array String3 of Example 7.6 is declared as an array of 50 elements, but when "PartTime" is assigned to String3, only the first eight array elements are used. Thus, the length of the string "PartTime" is 8.
In some algorithms (see Example 7.7 ), it is useful to know the length of a string that has been assigned to a given array of characters. For this purpose, programming languages contain a Length_Of() function, which we will write as follows:
Length_Of(String)
We have discussed this function earlier in the text and used it in several RAPTOR programs. We will now review its characteristics and applications in the context of character arrays.
The value of the Length_Of() function is the length of the given string or string variable and may be used in a program wherever a numeric constant is valid. For example, when code corresponding to the following pseudocode is run:
Declare Str[10] As Character
Set Str = "HELLO"
Write Length_Of(Str)
the output will be the number 5 because the string "HELLO" is made up of five characters.
Recall that when an array is declared, the number specified in the declaration statement determines the number of storage locations in the computer’s memory allocated to that array. If the array represents a string (an array of characters), then each storage location consists of one byte of memory. When a string is assigned to this array, the beginning elements of the array are filled with the characters that make up the string, a special symbol is placed in the next storage location, and the rest of the array elements remain unassigned. For example, a string named Str declared as an array of 8 characters and assigned the value "HELLO" can be pictured to look in memory as follows:
|
Address |
Str[0] |
Str[1] |
Str[2] |
Str[3] |
Str[4] |
Str[5] |
Str[6] |
Str[7] |
|
Contents |
"H" |
"E" |
"L" |
"L" |
"O" |
# |
|
|
Here, the symbol # represents the character that is automatically placed at the end of the assigned string. Thus, to determine the length of the string contained inStr, the computer simply counts the storage locations (bytes) associated with the variable Str until the terminator symbol, #, is reached.
Example 7.7 illustrates how the Length_Of() function can be used to validate input when that input must be within a certain range of characters.
Example 7.7 Using the Length_Of() Function To Validate Input
It is sometimes necessary to ensure that a string of text does not exceed a certain limit or is within a given range of allowable characters. The following program segment demonstrates the use of the Length_Of() function to validate that a user’s input for a username on a website is between 1 and 12 characters.
1 Declare Username[12] As Character
2 Declare Valid As Integer
3 Write "Enter your username. It must be at least 1 but ↵ no more than 12 characters:"
4 Input Username
5 Set Valid = Length_Of(Username)
6 While Valid < 1 OR Valid > 12
7 If Valid < 1 Then
8 Write "Username must contain at least one ↵ character. Please try again:"
9 Else
10 If Valid > 12 Then
11 Write "Username cannot be more than 12 ↵ characters. Please try again:"
12 End If
13 Input Username
14 Set Valid = Length_Of(Username)
15 End If
16 End While
What Happened?
The Length_Of() function finds out how many characters are in the character array, Username, and this integer is stored in Valid. Let’s discuss the logic in theWhile loop from line 6 through line 16. This loop will not be entered if Valid is a number between 1 and 12 so nothing will occur. But if Valid is either less than 1 or greater than 12, the loop will begin. If there is nothing stored in Username (i.e., Valid < 1), the If-Then statement on line 8 will execute. If this condition is not true, then Valid must be greater than 12 (or the loop would have been skipped) so line 11 will execute. Either way, a new Username is input (line 13) and its length is checked again on line 14.
Example 7.8 illustrates how strings can be manipulated by manipulating the arrays in which they are contained.
Example 7.8 Using the Length_Of() Function with Character Arrays
This program segment inputs a person’s full name with first name first, then a space, and then the last name. It stores the initials of that person as characters and displays the name in the following form: LastName, FirstName.
This pseudocode uses three strings. One stores the input name as FullName. The user is directed to enter his or her first name, then a space, and then the last name. The other two variables will store the first and last names as FirstName and LastName. It also makes use of two character variables to store the initials,FirstInitial and LastInitial. The trick to identifying which part of the input string is the first name and which part is the last name is to locate the blank space in the user’s entry.
We will assume that the following arrays and variables have been declared:
· Character arrays: FullName[30], FirstName[15], LastName[15]
· Character variables: FirstInitial, LastInitial
· Integer variables: J, K, Count
1 Write "Enter a name in the following form: firstname lastname:"
2 Input FullName
3 Set Count = 0
4 While FullName[Count] != " "
5 Set FirstName[Count] = FullName[Count]
6 Set Count = Count + 1
7 End While
8 Set FirstInitial = FullName[0]
9 Set LastInitial = FullName[Count+1]
10 Set J = 0
11 For (K = Count + 1; K <= Length_Of(FullName) − 1; K++)
12 Set LastName[J] = FullName[K]
13 Set J = J + 1
14 End For
15 Write LastName + ", " + FirstName
16 Write "Your initials are " + FirstInitial + LastInitial
What Happened?
After the person’s full name is input, the counter-controlled While loop on lines 4–7 assigns the characters in FullName to FirstName until the blank between the first and the last names is encountered. At this point, the value of Count is the length of FirstName, and because the blank corresponds to the index Count, the first character in LastName corresponds to the index Count + 1. Thus, the two assignment statements that follow the While loop on lines 8 and 9 correctly store the person’s initials. The new variable, J, (line 10) ensures that the letters of the last name are stored in the correct locations in the LastName array. TheFor loop on lines 11–14 copies the correct part of FullName to LastName. Finally, the Write statement on line 15 displays the person’s name, last name first with a comma between the two parts of the name. We also display the person’s initials, which have been stored in FirstInitial and LastInitial.
Array Indexes
In this chapter, we have emphasized the fact that the first element of an array is 0 and, therefore, an array with five elements will have index values from 0 to 4. However, this may not always be the case. Some programming languages use 1 as the beginning value for an array index. While this is rare nowadays, the program used in this book , RAPTOR, still uses an index of 1 as the first index of an array. All the other logic of dealing with arrays is the same but, when writing programs, this is a feature that must be considered. The Running With RAPTOR section of this chapter will give you practice dealing with this type of array.
Self Check for Section 7.3
1. 7.14 True or false? If a string variable Str has been declared to be an array of 25 characters, then the length of Str must be 25.
2. 7.15 Write a program segment to ensure that a user enters the year of his or her birth with exactly 4 digits.
3. 7.16 Suppose that a string variable, Name, has been declared as an array of characters and has been assigned a value. Write a program segment that displays the first and last characters of Name.
4. 7.17 Write a program segment that declares string variables String1 and String2 to be arrays of 25 characters, inputs a value for String1 from the user, and copies this value into String2.
7.4 Two-Dimensional Arrays
In the arrays you have seen so far, the value of an element has depended upon a single factor. For example, if one element in an array holds a student’s ID number, the value of this number depends on which student is being processed. Sometimes it’s convenient to use arrays whose elements are determined by two factors. For example, we might have several test scores associated with each student, in which case the value we look for would depend on two factors—the particular studentand the particular test in which we are interested. Another example might be the records of the monthly sales for salespeople for a year. Each salesperson has 12 numbers (one for each month’s sales) associated with him or her, so the value we look for would depend on which salesperson and which month is of interest. In these cases, we use two-dimensional arrays.
An Introduction to Two-Dimensional Arrays
A two-dimensional array is a collection of elements of the same types stored in consecutive memory locations, all of which are referenced by the same variable name using two subscripts. For example, MyArray[2,3] is one element of a two-dimensional array named MyArray. Example 7.9 illustrates one use of two-dimensional arrays.
Example 7.9 Introducing Two-Dimensional Arrays
Suppose we want to input the scores of 30 students in five tests into a program. We can set up a single two-dimensional array named Scores to hold all these test results. The first subscript of Scores references a particular student; the second subscript references a particular test. For example, the array elementScores[0,0] contains the score of the first student on the first test and the array element Scores[8,1] contains the score of the ninth student on the second test.
This situation may be easier to understand if you picture the array elements in a rectangular pattern of horizontal rows and vertical columns. The first row gives the scores of the first student, the second row gives the scores of the second student, and so forth. Similarly, the first column gives the scores of all students on the first test, the second column gives all scores on the second test, and so forth (see Figure 7.2 ). The entry in the box at the intersection of a given row and column represents the value of the corresponding array element. The following is shown in Figure 7.2 .
· Scores[1,3], the score of Student 2, Boynton, on Test 4, is 73
· Scores[29,1], the score of Student 30, Ziegler, on Test 2, is 76
Figure 7.2
The two-dimensional array named Scores
Declaring Two-Dimensional Arrays
Like their one-dimensional counterparts, two-dimensional arrays must be declared before they are used. We will use a declaration statement for two-dimensional arrays that is similar to the one we’ve been using for one-dimensional arrays. For example, we will declare the array of Example 7.9 using the following statement:
Declare Scores[30,5] As Integer
The numbers 30 and 5 inside the brackets indicate the number of elements in this array. This statement allocates 150(30 × 5) consecutive storage locations in the computer’s internal memory to hold the 150 elements of the array Scores. The Scores array has 30 rows and each row has 5 columns. Example 7.10 illustrates some basic points about using two-dimensional arrays.
Example 7.10 The Basics of Two-Dimensional Arrays
Consider the following pseudocode:
1 Declare ArrayA[10,20] As Integer
2 Declare ArrayB[20] As Integer
3 Declare FirstPlace As Integer
4 Set FirstPlace = 5
5 Set ArrayA[FirstPlace,10] = 6
6 Set ArrayB[7] = ArrayA[5,10]
7 Write ArrayA[5,2 * FirstPlace]
8 Write ArrayB[7]
What Happened?
Here, the Declare statements on lines 1 and 2 declare two arrays—the first, ArrayA, is two dimensional with 10 rows and 20 columns (200 elements) and the second, ArrayB, is one dimensional with 20 elements. Because FirstPlace is 5, the following is true:
· The assignment statement on line 5 sets ArrayA[5,10] equal to 6. In other words, the value of the 6th row, 11th column of ArrayA is equal to 6.
· The assignment statement on line 6 sets ArrayB[7] equal to the value of ArrayA[5,10], which is a 6. So now the value of the 8th element in ArrayB = 6.
· The Write statements on lines 7 and 8 display the value of the element in the 6th row, 11th column of ArrayA and the value of the 8th element of ArrayB so the number 6 will be displayed twice.
Using Two-Dimensional Arrays
As you have seen, counter-controlled loops, especially the For variety, provide a valuable tool for manipulating one-dimensional arrays. In the two-dimensional case, as shown in Example 7.11 , nested For loops are especially useful.
Example 7.11 Nested Loops for Loading a Two-Dimensional Array
This program segment inputs data into a two-dimensional array, Scores, whose elements are test scores. The first subscript of Scores refers to the student being processed; the second subscript refers to the test being processed. For each of the 30 students, the user is to input five test scores. The pseudocode is as follows:
1 Declare Scores[30,5] As Integer
2 Declare Student As Integer
3 Declare Test As Integer
4 For (Student = 0; Student < 30; Student++)
5 Write "Enter 5 test scores for student " + (Student + 1)
6 For (Test = 0; Test < 5; Test++)
7 Input Scores[Student,Test]
8 End For(Test)
9 End For(Student)
What Happened?
This pseudocode results in one input prompt for each student. The prompt instructs the user to enter the five scores for that student. For example, if the code corresponding to this pseudocode is run, the following text will be displayed:
Enter 5 test scores for student 1
and then execution will pause for input. After the user enters the five scores, he or she will see the following:
Enter 5 test scores for student 2
and so forth.
Example 7.12 demonstrates the use of nested loops to display the contents of the array.
Example 7.12 Using Nested Loops to Display the Contents of a Two-Dimensional Array
Suppose that a two-dimensional array Scores has been declared and assigned data as described in Example 7.11 . Student is an integer variable that is used to identify the element of Scores for a particular student’s record. Notice that, if the user enters a value of 4 for Student, this actually corresponds to the elements in the 4th row (subscript 3) of Scores. The following pseudocode displays the test scores of a student specified by the user:
1 Write "Enter the number of a student, and his or her test scores will be displayed."
2 Input Student
3 For (Test = 0; Test < 5; Test++)
4 Write Scores[Student − 1,Test]
5 End For
The pseudocode shown in Examples 6.11 and 7.12 is somewhat not user-friendly because it requires the user to refer to students by number (student 1,student 2, and so forth) rather than by name. Example 7.13 presents a more comprehensive example that corrects this defect by using a second (parallel) one-dimensional array of names.
Example 7.13 The Friendly Version Puts It All Together
This program inputs the names and test scores for a class of students and then displays each name and that student’s average test score. It uses a one-dimensional array, Names, whose elements are strings. This array holds the student names; a two-dimensional array, Scores, of numbers holds a numeric identification number for the student (the first value in the two-dimensional array) and that student’s 5 test scores.
We assume that there is a maximum of 30 students in the class, but that the exact number is unknown prior to running the program. Thus, we need a sentinel-controlled While loop to input the data. However, during the input process, we discover how many students are in the class, and we can use that number to process and display the array elements. For the sake of clarity, we declare all the variables used in this program.
1 Declare Names[30] As String
2 Declare Scores[30,5] As Integer
3 Declare Count As Integer
4 Declare Test As Integer
5 Declare K As Integer
6 Declare J As Integer
7 Declare StudentName As String
8 Declare Sum As Float
9 Declare Average As Float
10 Set Count = 0
11 Write "Enter a student's name; enter * when done."
12 Input StudentName
13 While StudentName != "*"
14 Set Names[Count] = StudentName
15 Write "Enter 5 test scores for " + Names[Count]
16 Set Test = 0
17 While Test < 5
18 Input Scores[Count,Test]
19 Set Test = Test + 1
20 End While(Test)
21 Set Count = Count + 1
22 Write "Enter a student's name; enter * when done."
23 Input StudentName
24 End While(StudentName)
25 Set K = 0
26 While K <= Count − 1
27 Set Sum = 0
28 Set J = 0
29 While J < 5
30 Set Sum = Sum + Scores[K,J]
31 Set J = J + 1
32 End While(J)
33 Set Average = Sum/5
34 Write Names[K] + ": " + Average
35 Set K + K + 1
36 End While(K)
What Happened?
By now you can easily recognize what many parts of the pseudocode do; therefore, rather than go through this program line by line, we will concentrate on the more advanced logic.
· Lines 1–12 declare all the variables, set the initial counter to 0, and get the “seed” value for the next loop (the first student’s name). To avoid inputting the sentinel value, “*”, into the array Names, we temporarily assign each input string to the variable StudentName. If the value of StudentName is not “*”, theWhile loop is entered and that string is assigned to the next element of Names. As soon as “*” is entered, the While loop is exited so it is never input into the Names array.
· The While loop on lines 13–24 is the most complicated part. It inputs the student names into the one-dimensional array, Names, and the five test scores into the two-dimensional array, Scores. How does it do this?
· The statement on line 14, Set Names[Count] = StudentName, loads the first student into the first element of the array, Names[0]. On the next time around this loop, the next name entered will be loaded into the second element of Names[1], and so forth.
· Line 15 asks the user to enter the five test scores for whichever student was entered on the previous line. The inner loop, on lines 17–20, loads each of the test scores into the two-dimensional array. The first dimension of this array, Scores[30, 5] is the number (Count) that identifies the student and the second dimension is a score. If Martin has been entered as the third student and his test scores are 98, 76, 54, 92, and 89, then the following values are stored in Scores:
· Scores[2,0] = 98
· Scores[2,1] = 76
· Scores[2,2] = 54
· Scores[2,3] = 92
Scores[2,4] = 89
· Line 21 increments the value of Count to prepare for the next student.
· After the five test scores for one student have been loaded into the two-dimensional array, lines 22 and 23 prompt for and input another student’s name. If there are no more students, Count has the value of the number of entries in the array, Names, and each student is identified in Scores by the number corresponding to his/her array subscript in Names. Note that Count has the value of the number of entries, which is one more than the highest subscript.
· When all the students and their test scores have been loaded into the two arrays, the program control goes to the outer While loop on lines 26–36. In effect, the outer loop says, "Using the student identified by number K, add up his/her test scores and divide that sum by 5 to get the average."
· The inner loop on lines 29–32 gets each test score and does the sum.
· Line 33 computes the average and line 34 displays the name of the student and his/her average.
· The outer loop makes another pass, as long as K (the variable that identifies the student) is less than or equal to Count − 1.
Higher Dimensional Arrays
Although they are not used very often, arrays with three or even more subscripts are allowed in some programming languages. These higher dimensional arrays can be used to store data that depends upon more than two factors (subscripts).
Self Check for Section 7.4
1. 7.18 How many storage locations are allocated by each statement?
· Declare A[4,9] As Integer
· Declare Left[10], Right[10,10] As Float
2. 7.19 A two-dimensional array named Fog has two rows and four columns with the following data:
3. 5 10 15 20
25 30 35 40
c. What are the values of Fog[0,1] and Fog[1,2]?
c. Which elements of Fog contain the numbers 15 and 25?
1. 7.20 What is displayed when code corresponding to the following pseudocode is executed?
1. Declare A[2,3] As Integer
1. Declare K As Integer
1. Declare J As Integer
1. Set K = 0
1. While K <= 1
1. Set J = 0
1. While J <= 2
1. Set A[K, J] = K + J
1. Set J = J + 1
1. End While(J)
1. Set K = K + 1
1. End While(K)
Write A[0,1] + " " + A[1,0] + " " + A[1,2]
1. 7.21 How many times are the prompts on lines 3 and 4 of the following pseudocode displayed?
1. 1 For (I = 0; I < 5; I++)
1. 2 For (J = 0; J < 12; J++)
1. 3 Write "Enter rainfall in state " + I
1. 4 Write " in month " + J
1. 5 Input Rain[I, J]
1. 6 End For(J)
7 End For(I)
1. 7.22 Imagine you own a small business that sells jewelry (rings, bracelets, and pendants) that you make. You create each piece in silver, gold, and stainless steel. Create a program that allows you to store the following data:
. each item’s name is stored in a one-dimensional array
. a two-dimensional array holds an identification number for each item plus the number of that item you have in stock in gold, silver, and stainless steel
7.5 Focus on Problem Solving: The Magic Square
A magic square is a two-dimensional array of positive integers, which has the following characteristics:
· The number of rows equals the number of columns
· All entries must be positive integers
· The sum of all the entries in each row, each column, and the two diagonals are identical
In a two-dimensional array, one diagonal goes from the upper left corner to the lower right corner and the other goes from the lower left corner to the upper right corner. The diagonals of a 3 × 3 square are shown here.
In this section, we will use the concepts in this chapter to create the pseudocode for a program that will allow a user to enter numbers into a two-dimensional array. The program will then test to see if the numbers entered form a magic square.
Problem Statement
The user should be prompted to enter values into a two-dimensional array. The values will be checked to ensure that the entries are positive integers. The values in the rows will be summed, the values in the columns will be summed, and the values in the diagonal elements will be summed. The sums will be compared. When one sum differs from another, a message will be displayed stating that these values do not form a magic square. If all the sums are the same, a message will be displayed stating that the values entered do form a magic square.
Problem Analysis
A magic square must be a two-dimensional array with the same number of rows and columns. We can think of a two-dimensional array as a matrix. A matrix is a rectangular grid of numbers. If there are M rows and N columns in the grid, we call it an M × N matrix (read this as “M by N matrix”). Therefore, our two-dimensional array should be a square or an N × N matrix, where N represents the number of rows and columns. While a magic square can consist of as many rows and columns as desired, for our purposes, we will use a 4 X 4 matrix—that is, an array with four rows and four columns. After the program is coded and tested, the number of rows and columns can be increased or decreased with one fell swoop of the keyboard—simply by changing the value assigned to the number of rows and columns.
1. Step 1: Populate the array. The array we use will be named Magic and each entry will be of the form Magic[A, B] where A represents the row and Brepresents the column. Getting the values for Magic requires input from the user. After each entry is input, we should validate it to ensure that it is a positive integer. We can do this with nested loops. The logic for this part, in general terms, is as follows:
2. Begin at the first column (column counter = 0)
3. While column counter < N (where N is the number of columns)
4. Set row counter to 0
5. While row counter < N
6. Get a value for this location: Magic[row, column]
7. Check if the value is a positive integer
8. Increase row counter
9. End While (row counter)
10. Increase column counter
End While (column counter)
11. Step 2: Do the sums. We need, at most, ten sums. There will be four sums of the values in the four rows, four sums of the values in the columns, and two sums of the values in the diagonals. However, we might not need to do all these sums. As soon as one sum does not match another sum, we know we do not have a magic square. So the logic for this part of the program, while a bit complex, is virtually all that is needed to complete this problem.
We can take one sum and compare it with all the subsequent sums. As soon as the sum differs from the first sum, we can jump out of the loop that does the sums and display the message that the data does not form a magic square.
In general terms, the logic for this part of the program will consist of a loop to sum the values of the rows, a loop to sum the values of the columns, and two sums for the diagonals. Before we begin to do all the sums, we can get an initial sum, store this value in an integer variable which we will call SumOne, and use it to compare each sum. As soon as one sum does not match SumOne, we can leave this part of the program and move on to Step 3.
12. Step 3: Display the results. The results are simple. Either the numbers entered by the user form a magic square or they do not.
The variables and the array needed for this program, therefore, are:
· Magic is a two-dimensional array with four rows and four colums
· RowCount is an Integer variable
· ColCount is an Integer variable
· rows and cols are two Integer variables
· SumOne and SumCount are two Integer variables
· Flag is a Boolean variable
· Diag1 and Diag2 are two Integer variables
· newSum is an Integer variable
Program Design
As with virtually all programs, we will begin this program with a welcome message. In this case, the welcome message will explain briefly what the program does and what is to be entered.
Thus, our program will consist of the following modules.
1. The Main module calls its submodules into action and displays the welcome message. It will explain what the user is to enter. Then it will, in sequence, call the other submodules that perform all the required processes.
2. The Enter_info module declares the array and accepts entries for each array element. When complete, control returns to the main module.
3. The Check_sums module gets an initial sum, then calls submodules to find the sums of the rows, the columns, and the diagonals:
a. Check_row_sums – sums each row in the array and compares each sum with the first sum.
b. Check_column_sums – sums each column in the array and compares each sum with the first sum.
c. Check_diag_sums – sums the two diagonals in the array and compares these sums with the first sum.
Each submodule will, at its end, either have Flag set to 1 or 0. When the Check_row_sums submodule returns control to the Check_sums module, if Flag is still 0, the Check_column_sums module will be called. If Flag is 1, the Check_sums submodule will end because the array has been identified as not a magic array. If Flag is still 0, the next submodule, Check_column_sums will be called. At the end of Check_column_sums, a similar situation exists. When control returns to Check_sums, either the Check_diag_sums will be called (if Flag is still 0) or the Check_sums module will end and return control to the mainmodule. Finally, if the Check_diag_sums module is called, when it is finished, it will return control to Check_sums which will then return control to main.
4. The Display_results module displays the results.
Passing Values to Submodules
In this section, as we have in the past, submodules are called and values are sent from one submodule to another with the assumption that they retain their values when passed from one place to another. It should be noted that we are doing this for simplicity at this point. In real programming languages a great deal of attention must be paid to how the values of variables are passed from one part of a program to another. Chapter 9 discusses this important concept in depth.
Keeping in mind that it is not always possible to use variables interchangeably from one submodule to another without special treatment that will be discussed later in the text, the pseudocode for each module follows:
Main Module
Start
Identify the program, explain to the user what to enter, and what will be determined (i.e., user entries will either form a magic square or not)
Call Enter_info submodule
Call Check_sums submodule
Call Display_results
End Program
Enter_info Module
This module will define some variables and will get input from the user to populate the two-dimensional array which we will call Magic. Since we have chosen to use a 4 X 4 matrix for our program, we will define the number of rows and columns to be 4. It is in this single place where, by changing this value, we can change the matrix size at one time and the program will still work.
The pseudocode for this module is as follows:
1 Declare cols, rows, ColCount, RowCount As Integer
2 Declare Magic[4, 4] As Integer
3 Set cols = 4
4 Set rows = 4
5 Set ColCount = 0
6 Set RowCount = 0
7 While RowCount < rows
8 While ColCount < cols
9 Write "Enter the value of the cell in row " + (RowCount + 1) ↵ + ", column " + (ColCount + 1)
10 Input Magic[RowCount, ColCount]
11 While ((Magic[RowCount, ColCount] != floor(Magic[RowCount, ↵ ColCount])) OR (Magic[RowCount, ColCount] < 0))
12 Write "Please enter a positive integer: "
13 Input Magic[RowCount, ColCount]
14 End While(Magic[RowCount, ColCount])
15 Set ColCount = ColCount + 1
16 End While(ColCount)
17 Set RowCount = RowCount + 1
18 Set ColCount = 0
19 End While(RowCount)
The logic used to input the values into this two-dimensional loop is similar to what we will use to determine all the sums so it is a good idea to spend a bit of extra time on the nested loops in this pseudocode. Each row of the array has four elements:
Magic[row0,col0], Magic[row0,col1], Magic[row0,col2], Magic[row0,col3]
Magic[row1,col0], Magic[row1,col1], Magic[row1,col2], Magic[row1,col3]
Magic[row2,col0], Magic[row2,col1], Magic[row2,col2], Magic[row2,col3]
Magic[row3,col0], Magic[row3,col1], Magic[row3,col2], Magic[row3,col3]
Lines 11–14 validate the user’s input, ensuring that only positive integers are stored in the array.
For each row, we need to get four inputs—one for each column. And we need to do this for four rows. The outer loop that begins on line 7 starts with RowCount = 0. The inner loop that begins on line 8 starts with ColCount = 0 and accepts input for four iterations. Each time the inner loop goes around a value of Magic is input. During this time, the value of the row (RowCount) does not change, but the value of the column (ColCount) is increased at the end of each iteration. Once the four columns on the first row have been filled, the inner loop is exited and RowCount is increased (line 17). The outer loop begins again, this time targeting the second row. The value of ColCount is set back to 0 (line 18) so the four columns of the second row are filled when the inner loop executes. This happens again and again until all the rows are filled. We will revisit this logic—using an outer loop to focus on one row and an inner loop to access each column in that row—when we create the modules to sum the rows, columns, and diagonals.
Check_sums Module
Once the array is populated, this module is called. It will first find a “test” sum (the sum of the first row of the array) which will be used to see if the other sums match and then it will call submodules to get the sums of the rest of the rows, the columns, and the diagonals. Recall that a magic square only exists if every sum matches every other sum. This is why we can initially pick any row or column as our test sum; if any other sum doesn’t match this one, there is no magic square. Here, we select the first row.
For the sake of efficiency, we will create this program so that it will stop finding sums when one sum doesn’t match the test sum. Therefore, we will use a Booleanvariable as a flag to indicate when a sum is found that does not match the test sum. A flag is a variable that can be set to false (or 0) initially and, when the data we are searching for is found, its value is changed to true (or 1). We will introduce three new variables here:
· SumCount is an Integer variable used to indicate a single row in the test sum
· SumOne is an two Integer variable that will hold the value of the test sum
· Flag is a Boolean variable
The pseudocode for this module is as follows:
1 Declare SumCount, SumOne As Integer
2 Declare Flag As Boolean
3 Set SumCount = 0
4 Set SumOne = 0
5 Set ColCount = 0
6 Set Flag = 0
7 While ColCount < cols
8 Set SumOne = SumOne + Magic[SumCount,ColCount]
9 Set ColCount = ColCount + 1
10 End While(ColCount)
11 Call Check_row_sums
12 If Flag == 0 Then
13 Call Check_column_sums
14 End If
15 If Flag == 0 Then
16 Call Check_diag_sums
17 End If
The loop that begins on line 7 calculates the sum of the four colums in the first row. This value is stored in SumOne and will now be used to compare every sum in the following three modules.
Line 11 calls the module to check the sums of the rows. If any of these does not match SumOne, the value of Flag will be set to 1, as we shall see in the next submodule. This will indicate that the array does not form a magic square. Once the rows have been summed, control from the Check_row_sums module will return to line 12 of this submodule. If Flag = 1, then no further sums need to be found. But if Flag still is 0, the columns and diagonals must be checked. Therefore, line 12 checks this condition and, if Flag is 0, the Check_column_sums module is called. Once all the columns have been summed, control returns to line 15 of this submodule. Again, the value of Flag is checked and, if it is still 0, the sums of the diagonal must be checked so the Check_diag_sums module is called.
Finally, when this submodule ends, control will return to the main module where the Display_results module will be called (line 16).
The Check_row_sums Module and the Check_column_sums Module
These two modules are almost identical so a detailed explanation is given only of the first; the pseudocode for the second will then be shown. The main difference between the two is that the variables identifying rows and columns will simply be switched.
In the Check_row_sums module, we begin by setting the row counter (RowCount) to 0. Nested loops are used. The outer loop identifies a single row. The inner loop adds up the values of all the column entries in that row. We will store that sum in a new integer variable, NewSum, which is set to 0 each time a new row sum begins. We also compare the value of NewSum whenever a row’s sum is finished with the value of OneSum from the previous module. If the two sums are the same, nothing happens. But if they are different, Flag is set to 1. Therefore, when the row sums are finished, if one row sum differs from OneSum, the Flag indicates that this is not a magic square.
The pseudocode for this module is as follows:
1 Set RowCount = 0
2 While RowCount < rows AND Flag == 0
3 Set NewSum = 0
4 Set ColCount = 0
5 While ColCount < cols AND Flag == 0
6 Set NewSum = NewSum + Magic[RowCount,ColCount]
7 Set ColCount = ColCount + 1
8 End While(ColCount)
9 If NewSum != OneSum Then
10 Set Flag = 1
11 End If
12 Set RowCount = RowCount + 1
13 End While(RowCount)
The pseudocode for the Check_column_sums module is almost the same but the outer loop identifies a single column and the inner loop sums up the rows in that column:
1 Set ColCount = 0
2 While ColCount < cols AND Flag == 0
3 Set NewSum = 0
4 Set RowCount = 0
5 While RowCount < rows AND Flag == 0
6 Set NewSum = NewSum + Magic[RowCount,ColCount]
7 Set RowCount = RowCount + 1
8 End While(RowCount)
9 If NewSum != OneSum Then
10 Set Flag = 1
11 End If
12 Set ColCount = ColCount + 1
13 End While(ColCount)
Check_diag_sums Module
The diagonals of our 4 X 4 matrix are the values shown in the grid below. The first diagonal, which we will call Diag1, starts at the upper left corner and ends at the lower right corner. The second diagonal, which we will call Diag2, starts at the lower left corner and ends at the upper right corner.
It would be easy to simply create these sums by using the values of these array elements. For example, the sum of the diagonals are:
Diag1 = Magic[0,0] + Magic[1,1] + Magic[2,2] + Magic[3,3]
Diag2 = Magic[3,0] + Magic[2,1] + Magic[1,2] + Magic[0,3]
However, we need to find a way to sum the diagonals that can be used for an N X N matrix of any size. This takes a bit more thought.
If we look at the rows and columns in each diagonal we notice several things. In Diag1, we want to add elements with increasing row and column values. If we write a loop to add values that have increasing row and column values in general, we can get the sum for Diag1, as follows:
1 Set Diag1 = 0
2 Set ColCount = 0
3 Set RowCount = 0
4 While RowCount < rows
5 Set Diag1 = Diag1 + Magic[RowCount,ColCount]
5 Set RowCount = RowCount + 1
6 Set ColCount = ColCount + 1
7 End While
For Diag2, however, we want to add the element that starts at the highest numbered row (the last row), first column to the element in the next highest row, second column, and so on until we get to the element in the first row, last column. We can use pseudocode that is almost identical to that of Diag1 but begin at RowCount = (rows − 1) (the highest row) and decrement RowCount for each iteration. This will also require that we change the test condition of the loop so that it ends afterRowCount is 0. The pseudocode for this part is as follows:
1 Set Diag2 = 0
2 Set ColCount = 0
3 Set RowCount = rows − 1
4 While RowCount >= 0
5 Set Diag2 = Diag2 + Magic[RowCount,ColCount]
5 Set RowCount = RowCount − 1
6 Set ColCount = ColCount + 1
7 End While
We could check whether each of these sums is the same as SumOne within each loop but, since there are only two diagonals and, regardless of the size of the array, there will always be only two diagonals, we can do this check in one step after we find both Diag1 and Diag2, as follows:
1 If Diag2 != SumOne OR Diag2 != SumOne Then
2 Set Flag = 1
3 End If
Control now returns to the last line of the Check_sums module which then returns control to the main module. The Display_results module is then called frommain.
The Display_results Module
This module is simple. If Flag is 1, a message is displayed to tell the user that the entries do not form a magic square. If Flag is still 0, a message is displayed, explaining that the entries do form a magic square. The pseudocode for this module is as follows:
1 If Flag == 1 Then
2 Write "Sorry, this is not a magic square."
3 Else
4 Write "Hooray! Your entries do form a magic square!"
5 End If
Program Code
The program code is now written using the design as a guide. At this stage, header comments and step comments are inserted, as necessary, into each module, providing internal documentation for the program.
Program Test
This program should be tested by using values that form a magic square and values that do not form a magic square. The simplest way to check if the program will identify a magic square is to enter all values that are the same such as all 1s or all 2s. However, you can search the Internet for more interesting values that will work. Two such solutions are provided below in Figure 7.3 . Almost any other entries that you use, selecting arbitrary values, will result in an array that does not form a magic square.
A working copy of this program, created in RAPTOR, is included with the Student Data Files but it would be a good exercise to create this program in RAPTOR yourself, if you have been using RAPTOR throughout the book. If you do this, remember that the test conditions and some initial values in RAPTOR loops must be reworked to ensure that the loop is exited when the test question is true and the loop is re-entered when the test condition is false as well as to account for the fact that RAPTOR arrays begin with the index value of 1. You can check the values given in Figure 7.3 to make sure your program correctly identifies a magic square.
Figure 7.3
Two ways to form a magic square
Self Check for Section 7.5
For Self Check Questions 7.23–7.27 refer to this section.
1. 23. Add code to the Enter_info module to display the values in Magic after the user enters his or her numbers.
2. 24. Add code to the Check_sums module to display the value of the initial sum, SumOne.
3. 25. Add code to the three submodules (Check_row_sums, Check_column_sums, and Check_diag_sums) to display the first sum (NewSum) that does not matchSumOne.
4. 26. Change the 4 X 4 array to a 6 X 6 array.
5. 27. Add code to give the user the option to select the size of the array.
7.6 Running With RAPTOR (Optional)
In RAPTOR, an array is created a bit differently from the way it has been done so far in this text. In the text, 0 is the first index of an array. This is the way most programming languages (such as C++ and Java) create arrays. However, in RAPTOR, the first element of an array has an index of 1. So, the first element of an array named RaptorItems is RaptorItems[1], the second element is RaptorItems[2], and so forth. Thus, a RAPTOR program to fill the RaptorItems array with the numbers 2, 4, 8, 16, and 32 would look as follows in the text’s pseudocode:
Set K = 1
While K <= 5
Set RaptorItems[K] = 2^K
Set K = K + 1
End While
You can see how this short program would look in RAPTOR in Figure 7.5 .
Although this is a minor difference between the text and RAPTOR versions of arrays, it has an important consequence. You must amend the pseudocode you create for text exercises involving arrays if you want these programs to work in RAPTOR. Specifically, when converting your pseudocode to a RAPTOR program, make sure that your arrays start with an index of 1, and you must make sure that any test conditions in loops that depend on array indexes are coded properly.
To declare an array in RAPTOR, you use an Assignment symbol, as you do for a variable but put square brackets ([ ]) after the array name. When you declare an array, you can set its size by putting a number inside the brackets. If you do not know initially how many elements you need, put in any number. RAPTOR will automatically add array elements, if needed, to your programs. You must, however, fill the array with an initial value. If your array is to be an array of numbers, the initial value for all the elements is normally set to 0; if it is to be an array of strings, the normal initial value will be the empty string (""); and if you want an array of characters, the normal initial value will be the blank space (' '). Figure 7.4 shows how various types of arrays, each named RaptorArray, are declared in RAPTOR.
Figure 7.5 shows the RAPTOR program that fills the array named RaptorItems with the values 2, 4, 8, 16, and 32 and the output in the MasterConsole.
Figure 7.4
Declaring and initializing arrays in RAPTOR
Figure 7.5
Filling an array in RAPTOR
In this section, we will use our programming skills with parallel arrays to create an application that can be used in a classroom. Our program will create a math test with questions created at random so that they are new each time a student takes the test. It will also grade the student’s test and output the results. However, before we begin this ambitious project, we will redo Example 7.3 from earlier in this chapter to practice how to use parallel arrays with RAPTOR.
A Short Example
Example 7.14 You’ll Be Sold on Parallel Arrays
We will repeat the pseudocode of Example 7.3 here and then create the program in RAPTOR. This program inputs the names of salespersons and their total sales for the month into two parallel arrays (Names and Sales) and determines which salesperson has the greatest sales (Max).
Pseudocode:
1 Declare Names[100] As String
2 Declare Sales[100] As Float
3 Set Max = 0
4 Set K = 0
5 Write "Enter a salesperson's name and monthly sales."
6 Write "Enter *, 0 when done."
7 Input Names[K]
8 Input Sales[K]
9 While Names[K] != "*"
10 If Sales[K] > Max Then
11 Set Index = K
12 Set Max = Sales[Index]
13 End If
14 Set K = K + 1
15 Write "Enter name and sales ↵ (enter *, 0 when done)."
16 Input Names[K]
17 Input Sales[K]
18 End While
19 Write "Maximum sales for the ↵ month: " + Max
20 Write "Salesperson: " + ↵ Names[Index]
RAPTOR implementation
In RAPTOR, Max is a reserved word so we have changed the name of the variable, Max, to Best. It is declared in our list of variables. Note that, because of the way RAPTOR handles the loop’s test condition, we changed the condition so that the loop will exit when the test condition is true. We also used K = 1 for the starting value since RAPTOR arrays begin with index = 1. The declaration of variables is shown followed by the RAPTOR implementation of the program.
Run It: Self-Grading Math Test
The program that we will create here will generate a simple math test with ten questions. The questions will be created by selecting two random numbers between1 and 100 and asking the student to give their sum. Student responses will be evaluated and, at the end, the student will get a grade and a list of questions that were missed. We use only ten simple addition problems in order to make the program easy to follow. However, once created, this program can be edited to make the math problems much more complex or to test different mathematical operations. The number of questions in the test can also be changed with ease.
If you want to create this program as you read this section, open a new RAPTOR program and save it with the filename grader.rap.
Problem Statement
This program will generate addition problems at random, get student inputs with the answers to each problem, compare student answers with the correct answers, and display the student’s grade and a list of questions that were answered incorrectly.
Developing and Creating the Program
There are several clearly defined aspects of this program which will make it easy to develop the program with submodules (i.e., subcharts). We need to create questions, get the student to take the test, grade the test, and display the results. Therefore, we will have the following subcharts:
· Variables: The subchart we normally create in RAPTOR as a matter of convenience to declare the variables used in the program.
· Load_questions: This subchart will load two parallel arrays. One will store the questions and the other will store the answers. These arrays will contain, in our program, ten elements each because our test will have ten questions. Each question will comprise two randomly generated numbers between 1 and 100.
· Take_test: This subchart will display the questions to the students and store his or her responses in another array. This new array will also be parallel to the two previously created arrays.
· Grade_test: In this subchart, each response is compared with the correct response by using a loop and parallel arrays. If a response is incorrect, a total of incorrect responses is incremented, and the question that corresponds to each incorrect response is stored in a new array. This list of incorrect responses will be displayed at the end.
· Display_results: This subchart will calculate the student’s score, using the number marked wrong and the total number of questions. It will display that score and the list of questions that were answered incorrectly.
For this program, the welcome message will be short and sweet. Besides the single line of output, the main module will only call the other submodules. Your mainmodule should look as shown. You can create the Calls and subcharts now and follow along as we develop the code for each subchart.
As we develop each module, we will add the variable declarations and their initial values to the Variables subchart.
The Load_questions subchart
We want to generate addition problems using two random numbers for each problem. We also need to keep track of the numbers generated because we will need them later on. Therefore, we will declare four arrays. The first and second, Num1 and Num2, are number arrays and will hold the ten pairs of numbers that we generate. Each pair—that is, Num1[1] and Num2[1], Num1[2] and Num2[2], and so on—will be used in a single addition problem. These arrays are parallel. The sum of any pair of numbers should be stored in a third parallel array, Answers, which is also of the number data type. The fourth parallel array, Questions, will be an array of strings and will hold the addition questions to be given to the student.
First declare and initialize these four arrays in the Variables subchart and declare a number variable, x.
Let’s take a moment to explain the variable x, which is the index value of these four arrays. We have said that this math test will have ten questions. But we may not want to go through ten questions each time we run a test to see if our program works. Similarly, we may decide in the future to double the number of questions in the test. By declaring a single number variable, here called x, and setting its value to a number, we can change the number of questions in the test (and everything else about the test, as you will see) by changing the value of x in one place. For this program, x = 10. This variable should be the first thing declared in the Variables subchart.
Why must x be declared before the arrays are declared? If you can’t think of the reason immediately, try to run your program (which will do nothing so far but should work without errors) both ways.
If x does not exist when it is used in the array declaration, you will get an error.
Now we are ready to create our addition problems.
The random function in RAPTOR: The random function in RAPTOR returns a number in the range of 0.0 up to but not including 1.0 , as we have discussed earlier in the text (see Chapter 6 ). The code to create a random integer between 1 and 100 is familiar. It uses the floor() function and is:
floor(random * 100) + 1
We will use a loop to load the ten elements of our two number arrays, Num1 and Num2 with random numbers. Our loop will begin at 1 and will continue for ten iterations or until our counter is larger than x.
However, we can complete two more tasks in this same loop. Once we have generated two random numbers, we can store their sum in the parallel array, Answers. We can also create the questions that the student will see and store those questions in the string array, Questions.
For each iteration through the loop, the counter, which we will call count, will increase by 1. We can also use count as the index value for each of the parallel arrays. The limit value of this loop will be the number of elements in the array (i.e., the number of questions in our test) so the test condition in the loop is count >x.
The Num1 and Num2 arrays will each hold a single random number. The addition question will ask the student what is the sum of these two numbers. The displayed question should be of the form:
"What is the sum of A + B?"
assuming A and B are numbers stored in Num1 and Num2, respectively.
We will create the statement that will store the question in the Questions array and will change for each new value of Num1 and Num2. We do this by concatenating text and the array values of Num1 and Num2, using count as the index value of all three arrays, as follows:
Questions[count] ← "What is the sum of " + Num1[count] + " + " + ↵ Num2[count] + "?"
The answers to each question should be stored in another parallel array, Answers. The answer to each addition question is the sum of the numbers in Num1 andNum2. When we use the + operator without concatenating any text, the computer performs the mathematical addition operation. We can load Answers with the sum of the two numbers generated at each iteration by using the following:
Answers[count] Num1[count] + Num2[count]
Therefore, the Load_questions subchart should look like this:
The Take_test subchart
For this submodule, we want the questions to be displayed, one at a time, and want to give the student a chance to enter an answer. We need one more array which we will call Responses. Create this array in the Variables subchart. As with all the other arrays, it will have x number of elements.
We need a loop to do one thing: display a question and store the response. We need to set a counter to 1. The loop should continue for as many questions as we have which, in this program is x. The loop, therefore, should end when the counter is greater than x. The Take_test subchart looks as shown.
The Grade_test subchart
This submodule is a little complicated. We want to compare the responses of the student (Responses) with the correct answers (Answers). Since our arrays are parallel, the comparison is easy. But we also want to keep track of how many answers are incorrect and, if an answer is incorrect, we want to hold that problem somewhere to display later so that the student knows where he or she made mistakes. We need to create one more array, called Incorrect, which should be created in the Variables subchart. Incorrect should also contain x elements. We need a variable to hold the number of incorrect responses. We will call that numeric variable wrong and, when it is declared in the Variables subchart, will have an initial value of 0.
Thus, the loop will have as many iterations as there are questions. For each iteration, it will compare a value of an element in Responses with the corresponding element in Answers. A Selection statement will be used at this point, and the branch taken will depend on the result of the comparison. If the value of Answers is the same as the value of Responses, we can store a message in the new array, Incorrect, that indicates that this answer was correct ("OK"). If the student’s response was incorrect (i.e., the value of Responses is not the same as the value of Answers), we need to increment the value of wrong, which keeps track of the number of incorrect responses and we also want to hold the incorrect question. We do this by storing the value of Questions for that element into the parallel element of Incorrect.
At the end of the loop, each element of the Incorrect array will either hold the value "OK" (when a student response was correct) or hold the value of a question that has been missed. The RAPTOR program that does these tasks is shown:
The Display_results subchart
This subchart will find the student’s grade on this math test and display that information as well as the number of questions missed. One new variable is needed which we will call score. Create this variable in the Variables subchart with an initial value of 0. The student’s score is simply the percent of correctly answered questions. We don’t know how many were answered correctly but we do know how many were answered incorrectly (wrong) and how many questions are there (x). So the number answered correctly is what’s left when the number wrong is subtracted from the total number. Multiplying this fraction by 100 turns the value into a percent:
score ((x − wrong)/x) * 100
We can then output messages telling the student his or her score (score) and the number incorrect (wrong). We also want to output a list of the missed questions. To do this, we need another loop with a nested decision structure. The loop will have x iterations. For each iteration, if the value of the corresponding element inIncorrect is "OK", nothing will happen. But if the value in an element of Incorrect is not "OK" then we know this was a missed question and we can display that value. In this way the output will consist of a list of all the questions missed by that student.
The flowchart for this subchart in RAPTOR is as shown in the next page:
Check It Out
It is now time for you to run your program. If you have created the program as shown in this section, your initial display would look similar to the one shown. Note, of course, that, since the questions are generated from random numbers, your questions will (and should) be different from those shown here. In fact, each time the program runs, the questions should be different. If they are not, you should recheck your program and make sure your random numbers are being generated correctly.
If, for example, you enter 3 incorrect responses, your final display should look similar to the one shown:
Generating More and More Math Tests
The beauty of this program is in its versatility. By changing the value of x in one place, you can have a test with 5, 50, 500 or as many questions as you want. By changing a few plus signs to minus, multiplication, or division signs you can have many different types of tests, although you might need to also change the syntax of the Questions array. You can increase or decrease the difficulty level of the test by changing the range of generated random numbers.
In fact, you could add a menu to the main program and offer various types of tests to the user. Then, depending on the user’s selection, Calls could be made to different subcharts which contain code almost identical to what we have created but altered slightly to generate very different math tests. This is how real-life programs are created. Whenever possible, a variable or an array is used in lieu of a hard-coded value to increase versatility. Altering this program to create different math tests will be part of the Programming Challenges in this chapter.
Chapter Review and Exercises
Key Terms
1. array
3. database
4. driver
6. flag
7. index number
8. list
9. matrix
11. parallel arrays
12. query
13. subscript
14. table
Chapter Summary
In this chapter, we discussed the following topics:
1. One-dimensional arrays as follows:
· The Declare statement is used to define a one-dimensional array with its data type
· Arrays and parallel arrays are used in input, processing, and output operations
· There are many advantages to using arrays, including reducing the number of program variables and creating more efficient and more general programs
2. The relationship between parallel arrays and databases
3. Viewing strings as arrays of characters as follows:
· A String variable can be declared as an array with elements that are of Character type
· The Length_Of() function is used to find the length of a String
· Strings can be manipulated by examining the array in which the string is located
4. Two-dimensional arrays as follows:
· Two-dimensional arrays are declared as Array[X,Y] where X represents the number of rows and Y represents the number of columns
· Two-dimensional arrays are used in input, processing, and output operations
Review Exercises
For each of the following Programming Challenges, use the modular approach and pseudocode to design a suitable program to solve it.
Fill in the Blank
1. 1. A variable that is used to indicate whether a certain action has taken place is called a(n) ____________.
2. 2. Each element in an array is identified by its __________.
3. 3. The Declare statement allocates ______________ storage locations to the array Name[25].
4. 4. The length of the string called MyName which contains the name "Arnold" is ______________.
5. 5. If the arrays Score1, Score2, and Score3 have the same size and the corresponding elements contain related data, they are said to be ____________ arrays.
True or False
1. 6. T F The elements of an array are stored in consecutive storage locations in the computer’s internal memory.
2. 7. T F One advantage of using subscripted variables (an array) is that they take up fewer storage locations than the same number of unsubscripted variables.
3. 8. T F An array may have some elements that are numbers and other elements that are strings.
4. 9. T F If a declaration statement allocates 100 storage locations to an array, the program must assign values to all 100 elements.
5. 10. T F The following statement:
Declare Array1[10], Array2[20] As Integer
allocates storage space for 200 variables.
6. 11. T F In two parallel arrays, all corresponding elements must be of the same data type.
7. 12. T F Array elements are normally stored in a computer’s memory in a sequence of consecutive storage locations.
8. 13. T F Parallel arrays must be of the same size.
9. 14. T F Parallel arrays must be of the same data type.
10. 15. T F A database consists of many tables.
11. 16. T F The length of a string in a Character array that has been declared as:
Declare Chr[10] As Character
is always 10.
12. 17. T F One- and two-dimensional arrays must be declared in the same statement.
13. 18. T F If we know that 100 elements have been allocated to the two-dimensional array A, then both subscripts of A must run from 0 to 9; that is, A must have 10 rows and 10 columns.
Short Answer
1. 19. Write a program segment that inputs up to 25 whole numbers (integers) from the user, terminated by 0, into an array called Numbers.
2. 20 Write a program segment that displays the contents of a previously declared array of strings called Names. Assume that the last entry in Names is "ZZZ", which should not be displayed.
3. 21. What is the output of code corresponding to the following pseudocode?
4. Declare N As Integer
5. Declare K As Integer
6. Declare X[100] As Integer
7. Set N = 4
8. Set K = 1
9. While K <= N
10. Set X[K] = K^2
11. Set K = K + 1
12. End While
13. Write X[N/2]
Write X[1] + " " + X[N − 1]
14. 22. What is the output of code corresponding to the following pseudocode if the user inputs 2, 3, 4, 5?
15. Declare Number As Integer
16. Declare Count As Integer
17. Declare Sums[5] As Integer
18. Set Count = 0
19. Set Sums[0] = 0
20. While Count < 4
21. Write "Enter a number: "
22. Input Number
23. Set Sums[Count + 1] = Sums[Count] + Number
24. Set Count = Count + 1
25. End While
26. While Count >= 0
27. Write Sums[Count]
28. Set Count = Count − 1
End While
29. 23. What is the output of code corresponding to the following pseudocode?
30. Declare A[20] As Integer
31. Declare B[20] As Integer
32. Declare K As Integer
33. For (K = 1; K <= 3; K++)
34. Set B[K] = K
35. End For
36. For (K = 1; K <= 3; K++)
37. Set A[K] = B[4–K]
38. Write A[K] + " " + B[K]
End For
39. 24. Explain why a variable that is used as a flag to indicate when a condition becomes true or false is normally a Boolean variable.
For Short Answer Questions 25 and 26 refer to the following pseudocode:
Declare Name[20] As Character
Declare K As Integer
Set K = 0
While K < 8
Set Name[K] = "A"
Set K = K + 1
End While
Set Name[8] = " "
Set Name[9] = "B"
40. 25. Write a single statement that displays the first and last characters in Name.
41. 26. Write a program segment that displays the characters in Name except the blank.
In Short Answer Questions 27–30, an array has been declared by the following:
Declare FullName[25] As Character
and contains a person’s first and last names, separated by a blank.
42. 27. Write a statement that displays the length of the string in the array FullName.
43. 28. Write a program segment that displays the number of letters in the person’s first name.
44. 29. Write a program segment that displays the person’s initials, with a period after each initial.
45. 30. Write a program segment that displays the person’s last name.
46. 31. Assume you are writing a program for a man who sells picture frames that he makes in his garage. List at least three types of information that he might require to be stored in parallel arrays if he wanted to keep track of his customer database.
47. 32. Write a program segment that declares a two-dimensional array X of integers with five rows and five columns and inputs 25 integers into this array from the user.
48. 33. Write a program segment that sums the elements in each row of the array X of Exercise 32 and displays these five numbers.
49. 34. What is the output of code corresponding to the following pseudocode?
50. Declare Q[10,10] As Integer
51. Declare R, C, As Integer
52. For (R = 1; R <= 3; R++)
53. For (C = 1; C <= 3; C++)
54. If R == C Then
55. Set Q[R,C] = 1
56. Else
57. Set Q[R,C] = 0
58. End If
59. End For(C)
60. End For(R)
61. For (R = 1; R <= 3; R++)
62. For (C = 1; C <= 3; C++)
63. Write Q[R,C]
64. End For(C)
End For(R)
Programming Challenges
1. 1. Input a list of positive numbers, terminated by 0, into an array Numbers[]. Then display the array and the largest and smallest number in it.
2. 2. Create a program that allows the user to input a list of first names into one array and last names into a parallel array. Input should be terminated when the user enters a sentinel character. The output should be a list of email addresses where the address is of the following form: [email protected]
3. 3. Input a list of employee names and salaries stored in parallel arrays. The salaries should be floating point numbers in increments of 100. For example, a salary of $36,000 should be input as 36.0 and a salary of $85,900 should be input as 85.9. Find the mean (average) salary and display the names and salaries of employees who earn within a range of $5,000 from the mean. In other words, if the mean salary is $45,000, all employees who earn between $40,000 and $50,000 should be displayed.
4. 4. Write a program that allows a small business owner to input, in parallel arrays, the type of item, its cost, and the number in stock. The program should output this information in the form of a table. You can assume that columns will be correctly formatted at a later time. The output will look something like this:
|
Item Name |
Cost |
Number in Stock |
|
Widget |
25.00 |
4 |
|
. |
. |
. |
|
. |
. |
. |
|
. |
. |
. |
|
Wombet |
47.50 |
9 |
5. Question 5 is designed specifically to accompany the Running With RAPTOR Math Test that was created in this chapter.
6. 5. Revise the Math Test created in the Running With RAPTOR section in this chapter to create a math exam that tests the following:
· There should be 20 division questions
· The questions should be of the form Num1 / Num2
· Num1 can be any number between 0 and 10, inclusive
· Num2 can be any number between 1 and 100, inclusive
· The output should include the student’s score, number wrong, and a list of the questions missed