Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

modifying an already loaded array

Status
Not open for further replies.

Guest_imported

New member
Jan 1, 1970
0
Ok I have to for my cobol data structures class delete duplicate records and report excess records. I have to read a txt file consisting of customer info into an array then determine which records are excess and which are duplicates. I have to then wait till after all records are loaded into the array to print it. My last semester of cobol I had to do something similar with a Transaction file and a Master file. However last semester I printed out the array while I was loading it. I never had to actually modify an array that was already loaded. If an record needed to be changed I would print the transaction-file-record instead of the master. If a file needed to be deleted I would simply code it so that record didn't print. ***I Quess what I am really asking is how do you modify an array after its already loaded? Specifically is there a way I can delete a record from an array after its already loaded into the array? I know this is a confusing and ambiguous post but please I would be very grateful for any help I can get.
 
Hi,

The first consideration is to ensure that the records in the array are sorted. You can then just loop down looking for duplicate keys. As for 'deleting' them from the array, I would suggest that adding a flag-byte to each element in the array might meet you requirements just mark each duplicate accordingly. If you must have a compacted array with duplicates eliminated just perform the above processing on ARRAY-A then invoke another loop to copy those that are not duplicates to ARRAY-B.

Regards,

Mike.
 
First, I have no idea of the meaning of excessive, so no hints about that.

If the incoming data are ordered (sorted) then you may easily eliminate duplicate records without ever placing them in the array. You merely check against the most recent record placed in the array. You might use the SORT verb to cause your incoming data to be ordered.

If the incoming data are unordered, then you still have the option of using an insertion technique that orders the array as you place records in the array; this also allows elimination of duplicates without ever placing the duplicates in the array. This insertion technique is known as an insertion sort, algorithms for which are available in several texts, including the classic by Donald Knuth.

If you place unordered data in the array, then you should either sort the array or use some brute force technique.

As far as 'eliminating' an array element:

What you are probably expected to do is to MOVE each array element with an index value higher than the index value of the array element to be eliminated to the next lower array element. E.g. assume I contains the occurrence number of the array element to be eliminated:
Code:
   PERFORM VARYING J FROM I BY 1
             UNTIL J = count of ARRAY-ELEMENT
       MOVE ARRAY-ELEMENT (J + 1)
         TO ARRAY-ELEMENT (J)
   END-PERFORM
Note "count of" may not work on all compilers.
Tom Morrison
 
Hi TMT,

How big is the file? Does it have a logical (not physical) key?, i.e. are they in some sequence? If it's not too big, perhaps you can can show it to us. It might spur some ideas.

Regards, Jack.
 
If you are deleting duplicate records that is a bit of an ambiguity. I would presume these records have some kind of field that uniquely identifies the person like an employee ID or SSN. Then you have to decide which one to keep as a master and wich one to discard.

If there are duplicates either you have a keyed file with duplicates allowed or a non-keyed file. If there is no file key, you can not really sort it unless you have a working file to sort it into or with. If you can only use tables one way to load the table is to search it for a match before you copy the new record or data into the table. Of course at that point you have to decide which record to keep or place in the excess or deleted table/file/report. You might have to sort the table. Sometimes that requires the programmer to make their own sort routine. If you do not like my post feel free to point out your opinion or my errors.
 
Hmmm, visitor not heard from in several days... Tom Morrison
 
S'funny, Tom; some people only like to ASK questions, not ANSWER them.

Regards, Jack.
 
My belief is that this problem was given to you
as a way of helping you acquire an understanding
of how use COBOL tables, rather than a question
of how machine efficient you can write code.

Therefore, I offer this solution :-

**** WS1 = Working Storage subscript
**** WT1 = Working Storage Table element, & all
**** WT... fields will require subscripting.
**** CAP = Table CAPACITY
**** SUB = general purpose SUBscript
**** HWM = High Water Mark (no of recs loaded into table)
01 WS1-CAP PIC 9(03) VALUE 50.
01 WS1-HWM PIC 9(03).
01 WS1-SUB PIC 9(03).
01 WS1-SCAN PIC 9(03).
01 WS1-SCAN-BGN PIC 9(03).
01 WS1-SHUF-BGN PIC 9(03).
01 WW-TABLE-1.
03 FILLER OCCURS 50 TIMES.
05 WT1-RECORD PIC X(80).
**** I am going to assume that none of the loaded
**** records contain all spaces.

2000-PROCESS.
PERFORM VARYING WS1-SUB FROM 1 BY 1
UNTIL WS1-SUB > WS1-HWM
IF WT1-RECORD(WS1-SUB) NOT = SPACES
PERFORM 2100-SCAN-FORWARD
END-IF
END-PERFORM.

2100-SCAN-FORWARD.
COMPUTE WS1-SCAN-BGN = WS1-SUB + 1.
PERFORM VARYING WS1-SCAN
FROM WS1-SCAN-BGN BY 1
UNTIL WS1-SCAN > WS1-HWM
IF WT1-RECORD(WS1-SCAN) = WT1-RECORD(WS1-SUB)
PERFORM 2110-SHUFFLE
END-IF
END-PERFORM.

2121-SHUFFLE.
COMPUTE WS1-SHUF-BGN = WS1-SCAN + 1.
PERFORM VARYING WS1-SHUF
FROM WS1-SHUF-BGN BY 1
UNTIL WS1-SHUF > WS1-HWM
MOVE WT1-RECORD(WS1-SHUF)
TO WT1-RECORD(WS1-SHUF -1)
END-PERFORM.
MOVE SPACES TO WT1-RECORD(WS1-HWM).
SUBTRACT 1 FROM WS1-HWM.


I hope I have not made any mistakes.
I haven't put this thru the compiler.
But the main thing I wanted to get across, is how
to use 'perform varying' and the concept of shuffling.

There are some nice things you can do with COBOL tables,
and over your career I hope you will discover them.

 
Please excuse my feeble minded excuse for a solution
to your question.
As others who read this forum would have undoubtedly
noticed, there are at least two mistakes :
(1) the modules 2110-SHUFFLE and 2121-SHUFFLE are
supposed to have the same name
(2) the logic is wrong - it wont work if there
are two duplicates in a row.
So here is my attempt to un-disgrace myself.

Note: There are some fields and modules which
I haven't included but they should hopefully
fairly self explanatory.

/CODE

*
FD L101-FILE.
01 L101-RECORD.
03 L101-TEST-FIELD PIC X(30).

*
01 WS1-SCAN-BGN PIC 9(03).
01 WS1-SCAN PIC 9(03).
*
01 WS1-CAP PIC 9(03) VALUE 50.
01 WS1-HWM PIC 9(03).
01 WS1-SUB PIC 9(03).
01 WW-TABLE-1.
03 WT1-ELT OCCURS 50 TIMES.
05 WT1-TEST-FIELD PIC X(30).
05 WT1-COUNT PIC 9(03).
*
PROCEDURE DIVISION.
*
0000-MAINLINE SECTION.
*
CONTROL-PARAGRAPH.
*
PERFORM 1000-INITIALIZE.
PERFORM 2000-PROCESS.
PERFORM 3000-FINALIZE.
*
GO TO Z-TERMINATE.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
1000-INITIALIZE SECTION.
*
CONTROL-PARAGRAPH.
*
DISPLAY SPACE AT 0101 WITH BG 1 FG 7.
*
PERFORM X-GET-L000-FILE-LOCN.
PERFORM X-GET-L101-FILE-LOCN.
PERFORM X-GET-L102-FILE-LOCN.
*
PERFORM X-OPEN-INPUT-L101.
PERFORM X-OPEN-OUTPUT-L102.
*
MOVE ZERO TO WW-RECORDS-READ-L101.
MOVE ZERO TO WW-RECORDS-WRITTEN-L102.
*
MOVE ZERO TO WS1-HWM.
MOVE ZERO TO WS1-SUB.
MOVE SPACES TO WW-TABLE-1.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
2000-PROCESS SECTION.
*
CONTROL-PARAGRAPH.
*
PERFORM 2100-TABLEIZE UNTIL WF-EOF-L101 = 'Y'.
PERFORM 2200-BLANK-OUT-DUPLICATES.
PERFORM 2300-REMOVE-EMBEDDED-BLANKS.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
2100-TABLEIZE SECTION.
*
CONTROL-PARAGRAPH.
*
PERFORM X-READ-L101.
IF WF-EOF-L101 = 'Y'
GO TO EXIT-PARAGRAPH
END-IF.
*
ADD 1 TO WS1-SUB.
MOVE L101-TEST-FIELD TO WT1-TEST-FIELD(WS1-SUB)
MOVE 1 TO WT1-COUNT(WS1-SUB).
MOVE WS1-SUB TO WS1-HWM.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
2200-BLANK-OUT-DUPLICATES SECTION.
*
CONTROL-PARAGRAPH.
*
PERFORM VARYING WS1-SUB FROM 1 BY 1
UNTIL WS1-SUB > WS1-HWM
IF WT1-TEST-FIELD(WS1-SUB) NOT = SPACES
PERFORM 2210-SCAN-FORWARD-FOR-DUPS
END-IF
END-PERFORM.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
2210-SCAN-FORWARD-FOR-DUPS SECTION.
*
CONTROL-PARAGRAPH.
*
COMPUTE WS1-SCAN-BGN = WS1-SUB + 1.
PERFORM VARYING WS1-SCAN FROM WS1-SCAN-BGN BY 1
UNTIL WS1-SCAN > WS1-HWM
IF WT1-TEST-FIELD(WS1-SCAN)
= WT1-TEST-FIELD(WS1-SUB)
MOVE SPACES TO WT1-ELT(WS1-SCAN)
ADD 1 TO WT1-COUNT(WS1-SUB)
END-IF
END-PERFORM.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
2300-REMOVE-EMBEDDED-BLANKS SECTION.
*
CONTROL-PARAGRAPH.
*
MOVE ZERO TO WS1-SUB.
PERFORM VARYING WS1-SCAN FROM 1 BY 1
UNTIL WS1-SCAN > WS1-HWM
IF WT1-TEST-FIELD(WS1-SCAN) NOT = SPACES
ADD 1 TO WS1-SUB
MOVE WT1-TEST-FIELD(WS1-SCAN)
TO WT1-TEST-FIELD(WS1-SUB)
END-IF
END-PERFORM.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
3000-FINALIZE SECTION.
*
CONTROL-PARAGRAPH.
*
*
PERFORM X-DUMP-TABLE-1.
*
PERFORM X-CLOSE.
*
DISPLAY ' ' AT 2401.
*
EXIT-PARAGRAPH.
EXIT.
*
*===========================================
*
X-DUMP-TABLE-1 SECTION.
*
CONTROL-PARAGRAPH.
*
PERFORM VARYING WS1-SUB FROM 1 BY 1
UNTIL WS1-SUB > WS1-HWM
MOVE SPACES TO L102-RECORD
MOVE WT1-TEST-FIELD(WS1-SUB)
TO L102-RECORD
MOVE WT1-COUNT(WS1-SUB)
TO L102-COUNT
PERFORM X-WRITE-L102
END-PERFORM.
*
EXIT-PARAGRAPH.
EXIT.
/CODE


If I didn't have to work on the assumtion that
the table had to be already loaded with the
duplicates, I would have done things differently.
For each read of the input file, I would have
scanned the table to see if it was already in there.
If it was I would simply add 1 to the count.
If it wasn't I would have added it at the
next available subscript (which would have
become the new high water mark) and moved
1 to the count.





 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top