Welcome to HBH! If you have tried to register and didn't get a verification email, please using the following link to resend the verification email.

Question on merging arrays in fortran 90


ghost's Avatar
0 0

Don't think you will have any problems helping me if you can programming even if you don't know fortran

Well I have a question that I'm having a bit of trouble. It works for some situations but doesn't for others. What the program does is takes two lists of numbers then calls a subroutine that sorts them in ascending order (lowest to highest) then calls another subroutine which merges them and puts them in ascending order. One condition is that you can't call the sorting subroutine in your merging subroutine to sort them. So you have to merge and sort at the same time is how I understand it.

The program has to work for these sets of lists: (a) List 1: 5, 3, 7, 1, 9 List 2: 2, 4, 6, 8, 10 (b) List 1: 10, 9, 6, 5, 4, 1 List 2: 3, 7, 2, 8 (c) List 1: 1, 2, 3, 7, 6, 4, 5 List 2: 9, 8, 10 (d) List 1: 10 List 2: 1, 9, 2, 8, 3, 7, 4, 6, 5

The problem seems to be with the merging of the arrays and not with the sorting because the sorting gives the correct output.

The merging works for (a) and (d) but doesn't work for (b) and (c).

When (b)'s lists are used here is the output:

Enter list: 10 9 6 5 4 1

How many items are in list two? 4
Enter list: 3 7 2 8

Sorted list one:
  1,  4,  5,  6,  9, 10
Sorted list two:
  2,  3,  7,  8
Merged List:
  1,  2,  3,  4,  5,  6,  7,  8,  9,***

When (c)'s lists are used here is the output:

Enter list: 1 2 3 7 6 4 5

How many items are in list two? 3
Enter list: 9 8 10

Sorted list one:
  1,  2,  3,  4,  5,  6,  7
Sorted list two:
  8,  9, 10
Merged List:
  1,  2,  3,  4,  5,  6,  7,  8,  0,  9

Here is my code for my subroutine

!--------------------------------------------------------------------
! This subroutine merges two sorted lists together in ascending order
!--------------------------------------------------------------------
    INTEGER,INTENT(IN)::list1(:), list2(:), num1, num2
    INTEGER,INTENT(OUT)::merged_list(40)
    INTEGER:: i, j, k, l
    i = 1
    j = 1
    k = 1
    DO l=1, num1+num2
	IF (list1(i) < list2(j)) THEN
	    IF (i>num1) THEN
		merged_list(k) = list2(j)
		j = j+1
		k = k+1
	    ELSE IF (j>num2) THEN
		merged_list(k) = list1(i)
		i = i+1
		k = k+1
	    ELSE IF (i>num1 .AND. j>num2) THEN
		EXIT
	    END IF
	    merged_list(k) = list1(i)
	    i = i+1
	    k = k+1
	ELSE IF (list1(i) > list2(j)) THEN 
	    IF (i>num1) THEN
		merged_list(k) = list2(j)
		j = j+1
		k = k+1
	    ELSE IF (j>num2) THEN
		merged_list(k) = list1(i)
		i = i+1
		k = k+1
	    ELSE IF (i>num1 .AND. j>num2) THEN
		EXIT
	    END IF
	    merged_list(k) = list2(j)
	    j = j+1
	    k = k+1
	END IF
    END DO
END SUBROUTINE merge```


Can someone help me get this working correctly please.

edit: also sorry about the mess it looks without any indentation

K3174N 420's Avatar
Satan > God
0 0
  1. order
  2. merge
  3. repeat

i don't know the language, but ill try and lay out some basic logic on the problem…

we have 2 lists of random random single digit numbers, we 1st need to change this to two lists of ordered numbers, followed by merging them to become 1 ordered string?

ORDER

  1. make a loop check and count the 1st string…
  2. get the loop to read through the numbers, each time returning the lowest value…
  3. write these returned values to a new string…
  4. repeat for 2nd string

MERGE 5. make a loop to check each digit of both strings and return which has the '0', and if it has a '1' after and so on until a number is missed… 6. write these numbers to the string 7. check the next string for he missing number… 8. if number is there, repeat, 9. else skip the number…

REPEAT 10. repeat whole process 4 times

i don't know if this helps, but when i write programs, i jot down the logic steps like this 1st to try and keep track.

as for that language your using, i don't know it.


ghost's Avatar
0 0

K3174N 420 wrote:

  1. order
  2. merge
  3. repeat

i don't know the language, but ill try and lay out some basic logic on the problem…

we have 2 lists of random random single digit numbers, we 1st need to change this to two lists of ordered numbers, followed by merging them to become 1 ordered string?

ORDER

  1. make a loop check and count the 1st string…
  2. get the loop to read through the numbers, each time returning the lowest value…
  3. write these returned values to a new string…
  4. repeat for 2nd string

MERGE 5. make a loop to check each digit of both strings and return which has the '0', and if it has a '1' after and so on until a number is missed… 6. write these numbers to the string 7. check the next string for he missing number… 8. if number is there, repeat, 9. else skip the number…

REPEAT 10. repeat whole process 4 times

i don't know if this helps, but when i write programs, i jot down the logic steps like this 1st to try and keep track.

as for that language your using, i don't know it.

Thanks for the suggestion but I should point out some things I guess.

  1. The 4 different examples aren't done at once. The program is run a separate time for each a, b, c and d.
  2. I have the sorting finished and it gives me the two lists sorted as you can see when I provided the two examples of b and c. The problem occurs when I try to merge the two sorted lists and have them in ascending order.
  3. There doesn't necessarily have to be every number from 1-10 so checking which array has a 1, then 2 then 3 wont be sufficient.

ghost's Avatar
0 0

Just keep track of the current indexes for each array and, while they're not all equal to the number of items in each - 1, increment a variable… check it against each array item, and increment the indexes as you pull items from it.

Basically:

Four index variables One counter variable

while (index1 < count(list1) - 1 and index2 < count(list2) - 1, etc.) { if list1[index1] == counter, then add it and increment index1 if list2[index2] == counter, then add it and increment index2 etc. increment counter }

It's long and winded, but I don't have the time to cook up a quicker or more efficient solution.


ghost's Avatar
0 0

Zephyr_Pure wrote: Just keep track of the current indexes for each array and, while they're not all equal to the number of items in each - 1, increment a variable… check it against each array item, and increment the indexes as you pull items from it.

Basically:

Four index variables One counter variable

while (index1 < count(list1) - 1 and index2 < count(list2) - 1, etc.) { if list1[index1] == counter, then add it and increment index1 if list2[index2] == counter, then add it and increment index2 etc. increment counter }

It's long and winded, but I don't have the time to cook up a quicker or more efficient solution.

Again this seems to assume that the two lists together will contain 1-10 without missing either one and without there being doubles of the same which could happen.


ghost's Avatar
0 0

ShapeShifters wrote: Again this seems to assume that the two lists together will contain 1-10 without missing either one and without there being doubles of the same which could happen. No, it doesn't… if it was expecting that, it would be shorter and not doing the repetition on each of the lists as it is. It accounts for doubles and accounts for as many numbers as it takes to go through all 4 lists. Don't skim.


ghost's Avatar
0 0

Not skimming, must just be misunderstanding your code.

Wouldn't

if list1[index1] == counter, then add it and increment index1 if list2[index2] == counter, then add it and increment index2 etc. increment counter

make the list[index] be something that is equal to the counter which since it's a counter, goes up by one each time?

I don't mean to insult you or anything, that's just what I gathered from looking at it. I'm probably looking at it wrong though it seems.


ghost's Avatar
0 0

ShapeShifters wrote: Not skimming, must just be misunderstanding your code.

Wouldn't

if list1[index1] == counter, then add it and increment index1 if list2[index2] == counter, then add it and increment index2 etc. increment counter

make the list[index] be something that is equal to the counter which since it's a counter, goes up by one each time?

It's fine; I wasn't insulted. Just seemed like a hasty appraisal. Here it is, in a nutshell:

  1. Each time you loop through, the counter is incremented… no matter what.
  2. The index for each list is only incremented when the indexed value equals the counter… because that value will be added to the master list and you need to move onto the next value.

Hope that's clearer.


ghost's Avatar
0 0

Ok, thanks that does make it clearer :)