3531lc01.summer2004

MULTIPLE DIMENSIONAL TABLES
. Up to seven levels of occurs in Cobol 85 are permitted.
. Three levels in COBOL 74 and earlier versions.
. Use multiple level tables for accumulating totals in arrays or storing multi-dimensional
tables in a program.
A. Defining a Two-Dimensional Array.
Consider an array of temperatures taken hourly for one week.
We could represent this in working storage as:
01
TEMPERATURE-ARRAY-1.
05 DAY-IN-WEEK OCCURS 7 TIMES.
10
1AM-TEMP
PIC 999.
10
2AM-TEMP
PIC 999
...
...
...
10
MIDNIGHT
PIC 999.
But, what about if there were readings taken every 15 minutes: We'd need a table with
96 entries! We have a better way to do this:
01
Temperature-Array-1.
05 Day-In-Week
Occurs 7 TIMES.
10
Hour
Occurs 24 TIMES.
15
Mean-Temp Pic 999.
This data structure represents a 7 x 24 array: 7 rows and 24 columns
==> 168 elements in the array; 504 bytes stored.
For each day in the week, there are 24 column entries: (1,1), (1,2), ... (1,24)
Access?
To access any specific temperatures, we need to access the element by
specifying both its row and its column entry.
Therefore, Mean-Temp(4,16) refers to day 4, 4pm sample;
Mean-Temp(7,2) refers to Day 7, 2 am sample...
We may write this as:
1
01
Temperature-Array-1.
05 Day-In-Week
10
Hour
Occurs 7 TIMES.
Occurs 24 TIMES
PIC 999.
and reference the array elements as Hour(x,y).
May be written this way, but "Mean-Temp" is more descriptive.
So it is ok too and means the same thing.
Use of Subscripts
First subscript = row (higher level occurs) and
Second subscript = column (lower level occurs) - "major and minor occurs"
Range: for a 7 x 24 array:
subscript 1 (row) can vary from 1 to 7, while
subscript 2 (column) can vary from 1 to 24.
Any extension yields "subscript out of range" and an abnormal end (abend).
Remember:
. to access any specific entry, you need both subscripts.
. subscripts must be enclosed in parentheses
. subscripts must be positive (not zero) integers or integer variables having
positive values.
. generally: the reference is: arrayb(n1,bn2)b
2
Accessing a 2-dimensional array:
(different from book)
print average temperature for a day and a week:
.......
600-average-rtne.
move 0 to weektotal
perform 700-loop-on-days varying day-sub from 1 by 1 until day-sub > 7.
compute weekly-average = weektotal/168
write printrec ... (with week average in it)
700-loop-on-days.
move 0 to daytotal
perform 800-loop-on-hours varying hour-sub from 1 by 1 until hour-sub > 24.
compute day-average = daytotal/24
write printrec ... (with day-average in it)...
800-loop-on-hours.
add mean-temp (day-sub,hour-sub) to daytotal, weektotal.
Using in-line performs:
move 0 to weektotal
perform varying day-sub from 1 by 1 until day-sub>7
move 0 to daytotal
perform varying hour-sub from 1 by 1 until hour-sub>24.
add mean-temp(day-sub,hour-sub) to daytotal, weektotal
end-perform
compute dayaverage = daytotal/24
write printrec......
end-perform
compute weekly-average = weektotal/168
write print-rec ......
Note the indentation!!!
How about the perform...varying...after?
Convenient when varying two nested subscripts with a single perform:
Varies minor subscript more rapidly than the major subscript.
So: perform p1 varying x from 1 by 1 until x > n1
after y from 1 by 1 until y > n2.
3
Consider a population array:
01
population-array.
05
state
10
cnty
15
pop
occurs 50 times.
occurs 10 times.
pic 9(10).
Problem: accumulate population of entire country.
move 0 to total.
perform p1 varying x from 1 by 1 until x > 50.
display "total-pop of us = " total
....
p1.
perform p2 varying y from 1 by 1 until y > 10.
p2.
add pop(x,y) to total.
Modify to print out each state's population????
move 0 to total.
perform p1 varying x from 1 by 1 until x > 50.
display "total-us population is: " total.
...
p1.
move 0 tot state-total.
perform p2 varying y from 1 by 1 until y > 10
display "state number" x "has population: " state-total.
...
p2.
add pop(x,y) to total, state-total.
Practice: Write these (above) as in-line Performs…

How about if we wanted to search the whole table and discover which state
and counties have a population greater than one million?
perform p1 varying x from 1 by 1 until x > 50 after y from 1 by 1 until y > 10.
...
p1.
if pop(x,y) > 1000000
display "state" x "and county" y "have population greater than one million."
4

Same problem, but count the total number of counties as well as the states
themselves that have a populations in excess of one million.
perform p1 varying x from 1 by 1 until x > 50.
display Athere are@ grand-tot
"number of counties in us with population in excess of one mission".
...
p1.
perform p2 varying y from 1 by 1 until y > 10.
display county-tot "number of counties in state A x
A have populations in excess of one million.".
add county-tot to grand-tot
move zeroes to county-tot.
p2. if pop(x,y) > 1000000
add 1 to county-tot
end-if.
Practice: Write this as an inline Perform…
Now, of course, let's print this out:
01
population-array.
05
state
10
cnty
15
pop
and
01 printline.
05
filler
05
county-print
10
pop-print
10
filler
occurs 50 times.
occurs 10 times.
pic 9(10).
pic x.
occurs 10 times.
pic Z(9)9.
pic X(5).
Discuss Aarray@ within printline...
move spaces to printline.
perform p1 varying x from 1 by 1 until x > 50.
....
p1.
perform p2 varying y from 1 by 1 until y > 10.
write printrec from printline after ......
p2.
move pop(x,y) to pop-print(y).
5
Using a two-dimensional array for accumulating totals.
Assume we are loading the population table for input.
Data is inputted in random order and each state has a "state number" and
each county has a "county number.".
01 inrec.
05
05
05
05
state
county
population
filler
pic 99.
pic 99.
pic 9(10).
X(the rest).* (I will take a few liberties now and then…  )
In working storage the table:
01
t-population-array.
05
t-state
occurs 50 times.
10
t-cnty
occurs 10 times.
15
t-pop pic 9(10).
note: changed the data names in table to prefix At@
why?
code:
read indata
at end
move 1 to f-eof
// What is this f-eof stuff??
end-read.
perform 100-load-table until f-eof=1.
...
100-load-table.
move population to t-pop(state,county).
read indata
at end
move 1 to f-eof
end-read.
Exercise: Recode last example with single in-line Perform containing
the READ and remaining functional code in it.
6
Perform until f-eof = 1
Read Indata
at end
move 1 to f-eof
not at end
move population to t-pop(state,country)
end-read
end-perform
Last example:
Load data into a two-dimensional array.
50 input records, one per state:
Input record format: (Where is this located in your program? Section? Division?)
01 inrec.
05
05
cnty
10
occurs 10 times.
c-pop
pic 9(10).
05
Could we have changed the prefix in the input record to something more meaningful,
such as in-cnty or in-pop??
01
t-population-array.
05
t-state occurs 50 times.
10
t-cnty occurs 10 times.
15
t-pop pic 9(10).
read infile
at end
move 1 to f-eof
end-read.
perform p1 varying x from 1 by 1 until x > 50
.....
p1.
perform p2 varying y from 1 by 1 until y > 10.
read infile
at end
move 1 to f-eof
end-read.
p2.
move c-pop(y) to t-pop(x,y).
7
Rewrite as in-line Perform….
Using in-line Performs:
Read infile
at end
move 1 to f-eof
not at end
perform varying x from 1 by 1 until x > 50 or f-eof = 1
perform y from 1 by 1 until y > 10
move c-pop(y) to t-pop(x,y)
end-perform do I need this scope terminator?
Read infile
at end
move 1 to f-eof
end-read
end-perform
end-read.
Note the scope terminators!
Note the indentation!
Several other ways this could have been written…..
What happens if I take the inner read out?
What happens if I delete the ‘or f-eof = 1?
What does this buy you?
8
Indexing
Consider the following table:
01
t-population-table.
05
t-state
occurs 50 times
10 t-county occurs 10 times
15
t-pop
indexed by x1.
indexed by x2.
pic 9(10).
"searching" => search the lowest level occurs
Search verb increments lowest level occurs only.
To search a multidimensional table using the search verb, we must control the "higher"
level index ourselves.
perform p1 varying x1 from 1 by 1 until x1 > 50.
....
p1.
set x2 to 1
search t-pop
at end
/* value of x2?? */
perform no-hit routine
when t-pop(x1,x2) = infield
perform 555-match-rtne
end-search.
Discuss.
Will this search entire table? (Be careful!!!)
Look at what is controlling the search verb…
9
How about searching "part" of a table:
To search a specific row: (State)
01
t-population-table.
05
t-state occurs 50 times
10 t-county occurs 10 times
15
t-pop
indexed by x1.
indexed by x2.
pic 9(10).
set x1 to 17
set x2 to 1
search t-pop
at end...
when ...
when ...
end-search.
Only searches row 17 ===>for first hit! (be careful!!)
Guidelines for searching an array or table:
When an array or table is to be searched for one specific entry or match, use
the Search verb. this is true because the search instruction stops as soon as
the When clause is satisfied.
When a table or an array is being searched where there may be multiple "hits"
or matches to be tabulated or counted, it is "better" to use perform...until or
nested performs and an if rather than a search.
Let=s consider more examples with indexing....
Let=s search a table (using Asearch@) and pick up all the hits...
10
01
t-population-table.
05
t-state occurs 50 times
10 t-county occurs 10 times
15
t- pop
indexed by x1.
indexed by x2.
pic 9(10).
(same table....)
set x1, x2 to 1
perform 100-search until x1 > 50
....next logic.....
100-search.
search t-pop
at end
set x2 to 1
set x1 up by 1
when
t-pop(x1,x2) = match-field
perform 555-match
end-search
105-next-para....
555-match.
do match logic....(whatever it is…; then, adjust values of indices)
if x2 = 10
set x2 to 1
set x1 up by 1
else
set x2 up by 1
end-if.
11
One more... tell the what this routine does....
Hint: Watch for the “control” on 100-SEARCH.
01
t-population-table.
05
t-state
10 t-county
15
t-pop
(same)
occurs 50 times
occurs 10 times
pic 9(10).
indexed by x1.
indexed by x2.
set x2 to 1
perform 100-search
varying x1 from 1 by 1 until x1>50
more....
100-search.
search t-pop
at end
set x2 up by 1
when
t-pop(x1,x2) = match-field
do match logic.....
....
end-search.
 Will get first hit (if any) per row!
Be able to do and understand these....
e.g.: Search an entire table
count number of occurrences with pop > 500,000
count number of occurrences with pop < 1000
count just number of states with pop < ? or > some value?? ....
12
Triple-level Occurs Clauses and More
In Cobol85 - seven levels
In Cobol 74 - three levels
01
Why do we care????
t-population-table.
05
t-state
occurs 50 times
10 t-county
occurs 10 times
15
t-district occurs 5 times
indexed by x1.
indexed by x2.
indexed by x3
pic 9(10).
50x10x5 = 2500 items (fields) of storage.
and each entry is 10 bytes; ==> 25000 bytes of storage
needed to store the table elements.
We have major, intermediate, and minor level items.
Say t-district (5,4,3) ==> state 5, county 4, and district 3.
Can have any variable too:
Can say t-district (5,x,y) ==> state 5 while counties and districts may vary.
Problem:
Sum the population (assuming table is loaded (populated)...) of state 5, county 4
and all of the districts in this county.
move 0 to sum.
perform varying x from 1 by 1 until x > 5
compute sum = sum + t-district(5,4,x)
end-perform
Make sure you study and understand the routines in your textbook.
I will use a different example: a pay table
13
Pay Table
Years of service is the column header, while rank is the row header:
0-2
2-4
4-6
6-8
8-10
Col
1000
1200
1400
1600
1800
Maj
800
1000
1200
1400
1600
2LT
600
800
1000
1200
1400
Clearly a 2-d table: three rows and five columns.
But now, I want to modify this table to factor in "reserve" salaries for the same ranks and
years of service:
How to draw / represent?
0-2
2-4
4-6
6-8
8-10
Col
1000/100
1200/120
1400/140
1600/160
1800/180
Maj
800/80
1000/100
1200/120
1400/140
1600/160
2LT
600/60
800/80
1000/100
1200/120
1400/140
So, we now have a three-dimensional table
Structure:
01
t-pay-table.
05
t-status
occurs 2 times indexed by x1.
10 t-rank
occurs 3 times indexed by x2.
15 t-years occurs 5 times indexed by x3.
20 t-pay
pic 9999.
with indices, Can still use subscripts
14
What does the following routine do?
perform p1 varying x from 1 by 1 until x > 2
after y from 1 by 1 until y > 3 after z from 1 by 1 until z > 5.
.......
p1.
if t-pay (x, y, z) > 800
display "pay status" x y z "equals/exceeds $800".
Better:
if t-pay (x, y, z) > 800
display "grade" y "with years of service" z
"and status " x "has salary >= to $800".
with table look ups for x, y, and z to print corresponding expansion literals!
What do I mean by ‘table look-ups?’
Consider table look-ups: Discuss:
Small example of use of Aredefines@ - but better used with larger numbers of literals...
01 expansion-tables.
05 rank-names.
10
pic x(7) value Acolonel@.
10
pic x(7) value Amajor@.
10
pic x(7) value A2lt@.
05 rank-tab
redefines rank-names occurs 3 times pic x(7).
05 status-names.
10
pic x(7)
value Areserve@.
10
pic x(7)
value Aactive@.
05 status-tab
redefines status-names occurs 2 times pic x(7).
05 years-nums.
10
pic x(7)
value Aover 2".
10
pic x(7)
value Aover 4".
10
pic x(7)
value Aover 6".
10
pic x(7)
value Aover 10".
05 years-tab
redefines years-nums occurs 5 times pic x(7).
Let’s look at the processing code…
if t-pay (x, y, z) > 800
display "grade" rank-tab(y)
"with years of service" years-tab(z)
"and status " status-tab(x)
"has salary >= to $800".
Discuss....
15
Can you write these as long non-numeric literals with continuation indicators in column 7?
Yes, but REAL pros and cons...
MORE EXAMPLES ON REDEFINES………………………………
In using the Redefines, you must set up your Values first. They must be explicitly
declared. One way, above. Another way, via non-numeric literals.
(See book: )
Consider:
01 T-month-data.
05
pic x(36) Value ‘
‘JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC’.
05
T-month-table
pic xxx occurs 12 times.
Understand what the T-month-table DOES! It ‘redefines’ the literal above it to be
accessible as 12 three-position alphanumeric fields…
Access?
T-month-table(4)
or T-month-table(x)…..
Read in value for month from ‘somewhere’
Assigned to ‘month’ in working storage, say, as …
05 month
pic 99.
Then, to access its corresponding literal, merely say:
Move T-month-table(month) to ……..{somewhere in printline…} …
Recognize that ‘month’ is simply a numeric integer field….See?
If data comes in ‘encoded’ or in a numeric form such that we want to print out or display
the expanded value, then table look ups are the way to do it.
In Program #1, you also need to print out the full month’s name in the second report.
How would you define the table and how would you access the month’s literal?
Exercise. Know how to do this…
16
Search for first occurrence of salary > 1500 and halt.
Use subscripts:
perform p1 varying x from 1 by 1 until x>2 or hit=1.
if hit = 1
display t-pay (x,y,z)
else
display "no hit. darn!"
end-if.
p1.
perform p2 varying y from 1 by 1 until y > 3 or hit=1
p2.
perform p3 varying z form 1 by 1 until z > 5 or hit=1.
p3.
if t-pay (x,y,z) >= 1500
move 1 to hit.
Same search using indices:
perform p1 varying x1 from 1 by 1 until x1 > 2 or hit=1
if hit = 1
display t-pay (x1,x2,x3)
else
display "no hit
end-if.
......
p1.
perform p2 varying x2 from 1 by 1 until x2>3 or hit=1
p2.
set x3 to 1
search pay
at end
move 0 to hit
when
pay (x1,x2,x3) > 1500
move 1 to hit
end-search.
17
Same thing with in-line Performs???
Perform varying x1 from 1 by 1 until x1>2 or hit = 1
Perform varying x2 from 1 by 1 until x2>3 or hit = 1
set x3 to 1
search pay
at end
move 0 to hit
when
pay(x1,x2,x3) > 15000
move 1 to hit
end-search
end-perform
if hit = 1
display t-pay(x1,x2,x3)
else
display ‘no hit, Sorry!’
end-if
end-perform
Convince yourself that this is equivalent code … or not.
If not, why not?
18
How about reading in a rank number and status value and searching./ summing/ qualifying
etc. for that particular rank and status:
01 search-transaction.
05
active-reserve
pic x.
05
rank
pic xxx.
05
additional-fields....
read infile
at end ........
end-read
if active-reserve = "a"
move 1 to x
else
move 2 to x.
/* assumes input is valid */
end-if.
if rank = "O6"
move 1 to y
else
if rank = "O4"
move 2 to y
else
move 3 to y
// valid assumption?? discuss.
end-if
end-if.
move 0 to sum.
perform p1 varying z from 1 by 1 until z > 5
divide sum by 5 giving average
......
p1.
add t-pay(x,y,z) to sum.
/* if accumulating ... */
or
if t-pay(x,y,z) > 1500
<action>
end-if.
/* if searching/qualifying */
Just process the "reserves"?
let x = 2; vary y from 1 to 3 and vary z from 1 to 5
reference:
t-pay (x,y,2) .......
19
Just process “majors” on “active duty:”
let x = 1, y = 3, and vary the z (years)
all ranks and statuses, but for years “over 6:”
References:
t-pay (x,y,3) varying x from 1 to 2
and y from 1 to 3
holding z (years) constant.
20
Table Quiz: Additional Exercises. Know These!
Create a structure such that we have five teachers each of which has three classes, an
d each of which has up to 30 students in each class who have names...
01
teacher-table.
05
t-teacher
occurs 5 times.
10
t-class
occurs 3 times.
15 t-student-name occurs 30 times pic x(20).
t-student-name (1,1,1) is the first student in the first class taught by the first
teacher....
Modify the structure such that we still have five teachers each of which has three
classes each of which has 30 students but also that the structure has the class name in it.
01
teacher-table.
05
t-teacher
occurs 5 times.
10 t-class
occurs 3 times.
15 t-class-name
pic x(15).
15 t-student-name occurs 30 times pic x(20).
References:
t-student-name (3,2,17) = ?
t-class-name (3,2) = ?
Lastly, modify the structure such that we have each teacher=s name....
Note: no occurs at the 01 level!!
01
teacher-table.
05
t-teacher
10 t-teacher-name
10 t-class
15 t-class-name
15 t-student-name
occurs 5 times.
pic x(20).
occurs 3 times.
pic x(15).
occurs 30 times pic x(20).
note: PIC clauses on elementary items only.
PIC clauses on the 10 level and 15 levels...
21
References: valid??
teacher-name (4) =
class-name (4,3) =
class-name (2,1) =
student-name (2,2,29) =
Can you Adraw@ these?? If you cannot draw these, you do not understand them and
will not be able to accurately access them.
22
REVIEW:
SEQUENTIAL SEARCH
BINARY SEARCH
ITEM BY ITEM SEARCH
SUCCESSIVELY HALVE THE TABLE
LOOKING FOR A HIT
TABLE MAY BE UNORDERED
TABLE MUST BE ORDERED
CONDITIONS: <, >, =
CONDITION: =
TABLE SIZE = ANY SIZE
TABLE SIZE ==> BETTER FOR LARGER
TABLES
MAX # OF PROBES
# OF TABLE ENTRIES
MAX # OF PROBES:
log2 table size
SEARCH
SEARCH ALL
SEARCH
AT END
WHEN < , >, =
END-SEARCH
SEARCH ALL
AT END
WHEN =
END-SEARCH
OCCURS CLAUSE
INDEXED BY
OCCURS CLAUSE
INDEXED BY
ASCENDING/DESCENDING KEY
23
Another example
Simple search:
01 table.
05
inventory-table occurs 100 times indexed by item-ind.
10
it-item-no
pic 9999.
10
it-item-description pic x(10).
10
it-item-price
pic 9(4)v99.
set item-ind to 1.
search inventory-table
at end
when
end-search.
(occurs clause)
(else)
(if ... then...)
Binary search:
01 tables.
05 inventory-table occurs 100 times
indexed by item-ind
ascending key it-item.
10
...
10
...
10
...
search all inventory-table
at end
when
end-search.
24
Comparisons
subscript
index
pic defined
indexed by clause in table, o
usage clause is indexed with no picture clause
any command;
arithmetic statements;
move
set, set up, set down, search,
search all
perform...varying; perform… until
perform...varying; perform…until
values = size of array
values of 0 to max number of bytes in table
position of entry
displacement of entry from in table from start of table
25