multidimensional array assignment

multidimensional array assignment

am 15.03.2006 07:30:20 von ronak

dear all,

I am a facing a problem in multidimensional array.

The problem is that when i am trying to copy the value of arry named
'str'
to one different array named 'temp', the value of 'str' (that is
source) itself is getting currepted.
With reference to my source code given below, when I am running the
program, it is showing different values for 'str' at two positions
indicated by names 'pos-1' and 'pos-2'.
Between positions 'pos-1' and 'pos-2' the array 'str' is used only
once, and that also as a source.
but still its value is getting changed at position 'pos-2'.


the program is given below

Ronak

#my @str = ();
print "Enter a string\n";
##$str=;
@string=split(/ /,);
chomp @string;
print "@string\n";
$n=@string;
$dn=$n-1;

my @str = ( [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,
0, 0, 0], [0, 0, 0, 0, 0] );
my @temp = ( [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,
0, 0, 0], [0, 0, 0, 0, 0] );
## $str[0][0]=0; $str[0][1]=0; $str[0][2]=0; $str[0][3]=0;
$str[0][4]=0;
## $str[1][0]=0; $str[1][1]=0; $str[1][2]=0; $str[1][3]=0;
$str[1][4]=0;
## $str[2][0]=0; $str[2][1]=0; $str[2][2]=0; $str[2][3]=0;
$str[2][4]=0;
## $str[3][0]=0; $str[3][1]=0; $str[3][2]=0; $str[3][3]=0;
$str[3][4]=0;
## $str[4][0]=0; $str[4][1]=0; $str[4][2]=0; $str[4][3]=0;
$str[4][4]=0;
##
## $temp[0][0]=0; $temp[0][1]=0; $temp[0][2]=0; $temp[0][3]=0;
$temp[0][4]=0;
## $temp[1][0]=0; $temp[1][1]=0; $temp[1][2]=0; $temp[1][3]=0;
$temp[1][4]=0;
## $temp[2][0]=0; $temp[2][1]=0; $temp[2][2]=0; $temp[2][3]=0;
$temp[2][4]=0;
## $temp[3][0]=0; $temp[3][1]=0; $temp[3][2]=0; $temp[3][3]=0;
$temp[3][4]=0;
## $temp[4][0]=0; $temp[4][1]=0; $temp[4][2]=0; $temp[4][3]=0;
$temp[4][4]=0;

my $i = 0; $j = 0; $k = 0; $l = 0;

for($m=0; $m<$n; $m++)
{
$str[$m][0]=($string[$m])
}
for($i=1; $i<=$n-1; $i++)
{
print "\n\n\n\nstr is = $str[1][0]$str[1][1]\n";
for($j=0; $j<=$dn-1; $j++)
{ if($j==0){print "j=0,$str[0][0]$str[0][1]\n";}
if($j==1){print "j=1,str[1][0]=$str[1][0], str[1][1]=$str[1][1]\n";}
for($k=$j+1; $k<=$dn; $k++)
{
print "\n\npos-1";
&printstr;
for($l=0; $l<=$i-1; $l++)
{
if($j==0)
{
## print "\nbefore
str[$j][$l]=$str[$j][$l],temp[$k-1][$l]=$temp[$k-1][$l]";
my $mm = $k - 1;
$temp[$mm][$l] = $str[$j][$l];
## print "\nafter
str[$j][$l]=$str[$j][$l],temp[$k-1][$l]=$temp[$k-1][$l]";
}
}
print "\n\npos-2";
&printstr;
print "$str[$k][$i-1] ";
if($j==0)
{
$temp[$k-1][$i]=$str[$k][$i-1];
}
print "\n\npos-3";
&printstr;
}
print "\n";
}
$dn--;
print "\nBefore Assignment";
&printstr;
@str=@temp;
print "\nAfter Assignment";
&printstr;
# print "j=0,$str[0][0]$str[0][1]$str[0][2]$str[0][3]\n";
# print "j=1,$str[1][0]$str[1][1]$str[1][2]$str[1][3]\n";
# print "j=2,$str[2][0]$str[2][1]$str[2][2]$str[2][3]\n";
}

sub printstr {
print "\nPrinting STR";
print "\nj=$j";
print "\n$str[0][0],$str[0][1],$str[0][2],$str[0][3],$str[0][4]";
print "\n$str[1][0],$str[1][1],$str[1][2],$str[1][3],$str[1][4]";
print "\n$str[2][0],$str[2][1],$str[2][2],$str[2][3],$str[2][4]";
print "\n$str[3][0],$str[3][1],$str[3][2],$str[3][3],$str[3][4]";
print "\n$str[4][0],$str[4][1],$str[4][2],$str[4][3],$str[4][4]\n" ;

Re: multidimensional array assignment

am 15.03.2006 08:53:38 von Kalle Olavi Niemitalo

"ronak" writes:

> @str=@temp;

This is a shallow copy. @temp is an array of references to
arrays. After the copy, @str will contain references to the same
arrays: @str and @temp are different arrays, but $str[$mm] refers
to the same array as $temp[$mm] does. So, when the next iteration
modifies $temp[$mm][$l], it is also modifying $str[$mm][$l].

I suppose the easiest way to construct new second-level arrays is:

@str = map [@$_], @temp;

If you want an even deeper copy, the Clone module might do the job.

Re: multidimensional array assignment

am 15.03.2006 10:01:11 von jurgenex

ronak wrote:
> I am a facing a problem in multidimensional array.

I am facing a problem with reading your code

> The problem is that when i am trying to copy the value of arry named
> 'str'
> to one different array named 'temp', the value of 'str' (that is
> source) itself is getting currepted.
> With reference to my source code given below, when I am running the
> program, it is showing different values for 'str' at two positions
> indicated by names 'pos-1' and 'pos-2'.
> Between positions 'pos-1' and 'pos-2' the array 'str' is used only
> once, and that also as a source.
> but still its value is getting changed at position 'pos-2'.
>
>
> the program is given below

Good, at least some source code.

Missing
use strict;
use warning;

> #my @str = ();

Please remove lines that are not used instead of commenting them out.
Leaving them in makes your code quite unreadable.

> print "Enter a string\n";
> ##$str=;
> @string=split(/ /,);
> chomp @string;
> print "@string\n";
> $n=@string;
> $dn=$n-1;
>
> my @str = ( [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,
> 0, 0, 0], [0, 0, 0, 0, 0] );
> my @temp = ( [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,
> 0, 0, 0], [0, 0, 0, 0, 0] );
> ## $str[0][0]=0; $str[0][1]=0; $str[0][2]=0; $str[0][3]=0;
> $str[0][4]=0;
> ## $str[1][0]=0; $str[1][1]=0; $str[1][2]=0; $str[1][3]=0;
> $str[1][4]=0;
> ## $str[2][0]=0; $str[2][1]=0; $str[2][2]=0; $str[2][3]=0;
> $str[2][4]=0;
> ## $str[3][0]=0; $str[3][1]=0; $str[3][2]=0; $str[3][3]=0;
> $str[3][4]=0;
> ## $str[4][0]=0; $str[4][1]=0; $str[4][2]=0; $str[4][3]=0;
> $str[4][4]=0;
> ##
> ## $temp[0][0]=0; $temp[0][1]=0; $temp[0][2]=0; $temp[0][3]=0;
> $temp[0][4]=0;
> ## $temp[1][0]=0; $temp[1][1]=0; $temp[1][2]=0; $temp[1][3]=0;
> $temp[1][4]=0;
> ## $temp[2][0]=0; $temp[2][1]=0; $temp[2][2]=0; $temp[2][3]=0;
> $temp[2][4]=0;
> ## $temp[3][0]=0; $temp[3][1]=0; $temp[3][2]=0; $temp[3][3]=0;
> $temp[3][4]=0;
> ## $temp[4][0]=0; $temp[4][1]=0; $temp[4][2]=0; $temp[4][3]=0;
> $temp[4][4]=0;

I honestly don't understand that part above. Why do you explicitely define
the fourth elements of each subarray in @str and @temp again to be 0? You
just set them to 0 already in the two top lines.

> my $i = 0; $j = 0; $k = 0; $l = 0;

Usually it is more readable to define variables when they are used first
instead of in one big blob.

> for($m=0; $m<$n; $m++)

Most people will find
for my $m (0..$n-1)
easier to read

> {
> $str[$m][0]=($string[$m])
> }
> for($i=1; $i<=$n-1; $i++)


Most people will find
for my $i (1..$n)
easier to read.

BTW: white space is not a scarce resource. Proper indentation is makes
reading code a lot easier, too.

> {
> print "\n\n\n\nstr is = $str[1][0]$str[1][1]\n";
> for($j=0; $j<=$dn-1; $j++)
> { if($j==0){print "j=0,$str[0][0]$str[0][1]\n";}
> if($j==1){print "j=1,str[1][0]=$str[1][0], str[1][1]=$str[1][1]\n";}
> for($k=$j+1; $k<=$dn; $k++)

This is getting too convoluted and too hard to read.
What on earth are you doing there?

> {
> print "\n\npos-1";
> &printstr;

Why are you using the & notation to call the sub? Do you know what the & is
doing and are you sure you need that functionality?

> for($l=0; $l<=$i-1; $l++)

Using the lower case letter l a variable name is not a good idea because in
most fonts it can be confused with the digit 1 too easily.

[giving up at this point, large part of unreadable code snipped]

> sub printstr {
> print "\nPrinting STR";
> print "\nj=$j";
> print "\n$str[0][0],$str[0][1],$str[0][2],$str[0][3],$str[0][4]";
> print "\n$str[1][0],$str[1][1],$str[1][2],$str[1][3],$str[1][4]";
> print "\n$str[2][0],$str[2][1],$str[2][2],$str[2][3],$str[2][4]";
> print "\n$str[3][0],$str[3][1],$str[3][2],$str[3][3],$str[3][4]";
> print "\n$str[4][0],$str[4][1],$str[4][2],$str[4][3],$str[4][4]\n" ;

Holy cow! What a beautiful piece of code set in block format.
You know you can replace this whole mumble-jumble with an easy double loop?

for my $outer(0..4) {
print "\n";
for my $inner (0..4) {
print $str[$outer][$inner];
}
}


What I still don't understand is why you believe that your problem has
anything to do with modules. You are neither using one nor trying to
implement one.

jue