How do I merge two arrays or two strings?

N

nntp

Let's say I have two arrays, one has N elements and the other has M. Both N
and M vary. I want to merge the two like you shuffle two decks of cards.
from
1 2 3 4 5 6 7 8
a b c d e f g h
to
12a34bc5def78gh

Both still need to be in the original order.

The second part of the question is when they are not arrays but two long
strings, I need to randomly select the N break points (break point must be a
whitespace) of string A. How do I do this?
 
S

Sherm Pendley

nntp said:
Let's say I have two arrays, one has N elements and the other has M. Both N
and M vary. I want to merge the two like you shuffle two decks of cards.
from
1 2 3 4 5 6 7 8
a b c d e f g h
to
12a34bc5def78gh

This smells a *lot* like homework, so I'm going to restrict this to
hints - you'll need to write the code yourself.

Have a look at the push() and shift() functions. Push() adds an element
to the end of an array, and shift() removes and returns the first
element from an array.

So, create a while() loop that repeats for as long as either M or N has
anything in it. Each time through the loop, choose an array at random,
shift() the first element from it, and push() that element onto the
target array.
Both still need to be in the original order.

In order??? Remind me not to play cards with you... :)
The second part of the question is when they are not arrays but two long
strings, I need to randomly select the N break points (break point must be a
whitespace) of string A. How do I do this?

What do you mean by "select"?

sherm--
 
T

Tad McClellan

nntp said:
Let's say I have two arrays, one has N elements and the other has M. Both N
and M vary. I want to merge the two like you shuffle two decks of cards.
from
1 2 3 4 5 6 7 8
a b c d e f g h
to
12a34bc5def78gh

Both still need to be in the original order.


Errr, yes, but did you mean to ask a question?

What do you want?

An algorithm?

Code?

What have you tried so far?

etc...



This should get you started:

--------------------------
#!/usr/bin/perl
use warnings;
use strict;

my @n = qw/1 2 3 4 5 6 7 /;
my @m = qw/a b c d e f g h/;

my @shuffled;
while ( @n + @m ) {
foreach my $i ( 1 .. int(1 + rand 3)) {
push @shuffled, shift @n if @n;
}
foreach my $i ( 1 .. int(1 + rand 3)) {
push @shuffled, shift @m if @m;
}
}

print $_ for @shuffled;
print "\n";
--------------------------

The second part of the question is when they are not arrays but two long
strings, I need to randomly select the N break points (break point must be a
whitespace) of string A. How do I do this?

1) make an array of the character positions
( push @bp, pos()-1 while /\s/g; )

2) make a random selection from that array
 
N

nntp

nntp said:
Errr, yes, but did you mean to ask a question?

What do you want?

An algorithm?

Code?

What have you tried so far?

etc...



This should get you started:

--------------------------
#!/usr/bin/perl
use warnings;
use strict;

my @n = qw/1 2 3 4 5 6 7 /;
my @m = qw/a b c d e f g h/;

my @shuffled;
while ( @n + @m ) {
foreach my $i ( 1 .. int(1 + rand 3)) {
push @shuffled, shift @n if @n;
}
could you tell me why 1 is always the start in @shuffled, which means, it is
not random.
also, could you explain what ( 1 .. int(1 + rand 3)) does? you call $i which
does not exist.
you tried to pick zero or one, but why rand 3?, will I get 1+3=4?
foreach my $i ( 1 .. int(1 + rand 3)) {
push @shuffled, shift @m if @m;
}
}

print $_ for @shuffled;
print "\n";
--------------------------



1) make an array of the character positions
( push @bp, pos()-1 while /\s/g; )
I did this
$_='what the heck does this do?';
( push @bp, pos()-1 while /\s/g; )
print "@bp\n";
it gave me errors;
Global symbol "@bp" requires explicit package name at testmerge.pl line 23.
syntax error at testmerge.pl line 23, near "1 while"
Execution of testmerge.pl aborted due to compilation errors.
 
E

Eugene Mikheyev

The second part of the question is when they are not arrays but two long
strings, I need to randomly select the N break points (break point must be a
whitespace) of string A. How do I do this?
my @a = split /\s/, $a;
my @b = split /\s/, $b;

And you've your first tas again
 
N

nntp

my @a = qw /1 2 3 4 5 6 7 8/;
my @b = qw /a b c d e f g h/;

my @c = map {shift @{@a && rand @a < @b && rand @b ? \@b : \@a}} 1 .. @a +
@b;

I think your code has some problems - as the last letter is always h, so it
is not 100% random, the same problme as the other code. Do you think RAND
has problems? I am usingn perl 5.6, so there is not srand problme in 5.6;

== The second part of the question is when they are not arrays but two long
== strings, I need to randomly select the N break points (break point must be a
== whitespace) of string A. How do I do this?

I've no idea what you mean by this question.


Abigail
--
package Just_another_Perl_Hacker; sub print {($_=$_[0])=~ s/_/ /g;
print } sub __PACKAGE__ { &
print ( __PACKAGE__)} &
__PACKAGE__
( )
 
A

Anno Siegel

[in reply to Abigil, attribution missing]
@b;

I think your code has some problems

Yes, precedence. "@a && rand @a < @b && rand @b" is parsed as
"(@a && rand @a < @b) && rand @b". It should be "(@a && rand @a) <
(@b && rand @b)".
- as the last letter is always h, so it

I never see "h" as the last choice.
is not 100% random, the same problme as the other code. Do you think RAND
has problems? I am usingn perl 5.6, so there is not srand problme in 5.6;

It isn't entirely clear what an "unbiased merge" would be under these
constraints. Abigail chooses an element from one of the lists according
to their relative (remaining) length, so the longer list gets better
chances. That looks pretty plausible, but the statistical properties
of the resulting merge would have to be investigated.

Anno
 
T

Tad McClellan

nntp said:
could you tell me why 1 is always the start in @shuffled, which means,


Because my code always shifts from @n first (above) and from @m second (below).

You couldn't see that for yourself?

Are you a Programmer?

it is
not random.


Yes, I did not write your program for you, I illustrated some techniques
that you could employ to write your program. So go write it, inserting
more randomness whereever appropriate.

Just add a rand() call to determine which order to examine the arrays in.

What's the problem?

also, could you explain what ( 1 .. int(1 + rand 3)) does?


Yes I could, but I don't want to until you've shown that you've
done your best to understand it on your own first.

Have you read the documentation for int() and rand()?

Was some part of that unclear to you?

Did you write a little test program with that code and see
what kind of numbers it gets you?

you call $i which
does not exist.


$i is a variable, you don't "call" variables, you call subroutines,
but $i is not a subroutine, so I dunno what you are talking about here...

you tried to pick zero or one,


No I didn't.

but why rand 3?,


Each part of the "fan" will be 1-3 cards from one of the arrays.

You will probably want to add some randomness in determining the
fan size too.

will I get 1+3=4?


If you add 1 and 3 you will get 4, yes.

If you want to know what numbers my code generates, write a little
test program with my code in it, and see what numbers in generates.

Did it generate any "4"s?

it gave me errors;


Then fix the error!

Global symbol "@bp" requires explicit package name at testmerge.pl line 23.


perldoc strict
perldoc -f my

and look up the description for that message in

perldoc perldiag
 
J

Jay Tilton

: Let's say I have two arrays, one has N elements and the other has M. Both N
: and M vary. I want to merge the two like you shuffle two decks of cards.
: from
: 1 2 3 4 5 6 7 8
: a b c d e f g h
: to
: 12a34bc5def78gh
:

#!perl
use strict;
use warnings;
use List::Util 'shuffle';
my @a = qw(1 2 3 4 5 6 7 8);
my @b = qw(a b c d e f g h);
my @c = map shift @{[\(@a, @b)]->[$_]}, shuffle( (0) x @a, (1) x @b );
__END__
 
A

Anno Siegel

Jay Tilton said:
: Let's say I have two arrays, one has N elements and the other has M. Both N
: and M vary. I want to merge the two like you shuffle two decks of cards.
: from
: 1 2 3 4 5 6 7 8
: a b c d e f g h
: to
: 12a34bc5def78gh
:

#!perl
use strict;
use warnings;
use List::Util 'shuffle';
my @a = qw(1 2 3 4 5 6 7 8);
my @b = qw(a b c d e f g h);
my @c = map shift @{[\(@a, @b)]->[$_]}, shuffle( (0) x @a, (1) x @b );
__END__

Ah... using shuffle(). Nice solution.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top