Qbasicnews.com December 12, 2019, 10:08:33 AM  Pages: Author Topic: interleaving 2 arrays  (Read 3108 times)
Mango
Wandering Guru   Posts: 360  « on: May 22, 2003, 04:25:01 PM »

I don't know if I should post this as a "challenge" or in the "programming help" section...anyway...here it is.  What I want to do is to take 2 arrays and interleave them, so that the values from each array are (approxamately) evenly distributed in a third array.  I know how to do this, but want to know if anyone has a more elegant way.  My method is to create a new array sized the sum of size of the 2 original arrays.   Then, this array is filled with alternating chuncks from each array.  The size of the chunk is determined by dividing the larger array by the smaller then inserting the whole number followed by a single element from the smaller array.

if, for example, array1 contained 3 elements elements: x,x,x
and arrat2 contained 11 elements: a,a,a,a,a,a,a,a,a,a,a

My method produces a third array containing:

aaaxaaaaxaaaax

I would like to have the elements more evenly distributed, for example: aaxaaaxaaaxaaa

Does anyone see an efficient way to do this?

Thanks.  The following snippet should get us started on the same page...

Code:
'INPUT "Number of elements in Array 1";s1
'Input "Range for values in array 1 (0 to ?)";r1
'Input "Number of elements in Array 2";s2
'input "range for values in array 2 (0 to ?)";r2

s1=100   'array1...100 elements between 0 and 5
r1=5
s2=20    'array2...20 elements between 0 and 30
r2=30

dim array1(1 to s1) as integer
dim array2(1 to s2) as integer

for x=1 to s1
array1(x)=rnd*r1   'fill array1 with values
next x

for x=1 to s2       'fill array2 with values
array2(x)=rnd*r2
next x

DIM array3(1 TO (UBOUND(a)-LBOUND(a))+(UBOUND(b)-LBOUND(b))) AS INTEGER

'How to fill array3 with interleaved elements of array1 and array2???

Thanks Logged
Mango
Wandering Guru   Posts: 360  « Reply #1 on: May 29, 2003, 10:05:55 PM »

since the mixing isn't critical, I decided to just use

xxaaaaaxx

to mix aaaaa with xxxx

thanks again Logged
Agamemnus
x/ \z     Posts: 3491  « Reply #2 on: May 30, 2003, 01:00:36 PM »

errr if it turns out to be critical...
say that second array is smaller than the first array.

Goes something like this (untested and prolly faulty):

Code:

ratio% = len.first.array% / len.second.array%
len.third.array% = len.first.array%+len.second.array%

extra% = (len.first.array% - ratio% * len.first.array%) / 2
if extra% > 0 then
extra1% = extra%/2
extra2% = extra%-extra1%
for i% = 1 to extra1%
third.array%(I%) = first.array%(I%)
next i%
for i% = len.third.array% - extra2% + 1 to len.third.array%
third.array%(I%) = first.array%(I%)
next i%
end if

for I% = extra%+1 to len.third.array% - extra%
if j%< ratio% then j% = j% + 1 else j% = 0
if j%>0 then third.array%(i%) = first.array%(i%) else third.array%(i%) = second.array%(i%)
next i% Logged

Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Mango
Wandering Guru   Posts: 360  « Reply #3 on: May 31, 2003, 02:23:50 AM »

Quote from: "Agamemnus"
errr if it turns out to be critical...
say that second array is smaller than the first array.

Goes something like this (untested and prolly faulty):

Thanks for the response.  It turns out that your code idea had some...um... problems  :roll: however, it got me thinking.  I was hoping there was an easier way than what I ended up using, since interleaving the arrays was just a very small part of a larger program...anyway...the following sub will do the trick with any 2 arrays.

The example shown uses text arrays to make the demo-display easy to understand.  However, the array mixer works fine on any datatype, as long as it's correctly specified in the call.

Code:
DEFINT A-Z
DECLARE SUB mix (small() AS STRING, large() AS STRING, combined() AS STRING)
CLS

DO

DO
INPUT "size of array1"; sa1
INPUT "size of array2"; sa2
LOOP UNTIL sa1 > 0 AND sa2 > 0

combosize = sa1 + sa2
REDIM array1(1 TO sa1) AS STRING
REDIM array2(1 TO sa2) AS STRING
REDIM combo(1 TO combosize) AS STRING

FOR x = 1 TO sa1
array1(x) = "x"
PRINT array1(x);
NEXT x

PRINT

FOR x = 1 TO sa2
array2(x) = "a"
PRINT array2(x);
NEXT x

PRINT

IF UBOUND(array1) > UBOUND(array2) THEN  'put small array first in argument list
CALL mix(array2(), array1(), combo())
ELSE
CALL mix(array1(), array2(), combo())
END IF

FOR x = 1 TO UBOUND(combo)
PRINT combo(x);
NEXT x

PRINT

LOOP
END

SUB mix (small() AS STRING, large() AS STRING, combined() AS STRING)

SAS = UBOUND(small)     'Small Array Size
LAS = UBOUND(large)      'Large Array Size
CAS = UBOUND(combined)  'Combined Array Size
TC = SAS + 1               'Total Chunks
SCS = LAS \ (SAS + 1)      'Small Chunk Size
LCS = SCS + 1              'Large Chunk Size
SAP = 1: LAP = 1: CAP = 1  'Small, Large, Combined Array Position
NLC = LAS - (SCS * TC)     'Number of large chunks

FOR x = 1 TO NLC                  'interleave starting with large chunks
FOR y = 1 TO LCS
combined(CAP) = large(LAP)
CAP = CAP + 1: LAP = LAP + 1

NEXT y
combined(CAP) = small(SAP)
CAP = CAP + 1: SAP = SAP + 1
NEXT x

FOR x = 1 TO TC - NLC              'interleave small chunks
FOR y = 1 TO SCS
combined(CAP) = large(LAP)
CAP = CAP + 1: LAP = LAP + 1

NEXT y
IF x = TC - NLC THEN EXIT SUB  'out of data...exit sub
combined(CAP) = small(SAP)
CAP = CAP + 1: SAP = SAP + 1
NEXT x

END SUB Logged
 Pages: