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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problemm with adding hash to hash of hash

Status
Not open for further replies.

retfos

Programmer
Joined
Aug 26, 2007
Messages
1
Location
PL
I wrote a subroutine to create a hash with numbers of transitions between states makred by binary codes in string. Length of codes is passed by parameter $rank and the second parameter is the string to analize. That is the code:

sub get_prob{
my ($file_content,$rank)=@_;
my %hash;
my %row;

$start_portion=get_portion_of_string($file_content,0,$rank);
$actual_portion=$start_portion;
$hash{$actual_portion}->{$actual_portion}=0;
$i=1;
$size=length($file_content);

while($i+$rank<=$size){
$next_portion=substr($actual_portion,1,$rank-1);
$next_portion.=substr($file_content,$i+$rank-1,1);

if (exists $hash{$actual_portion}{$next_portion}){
# there is transition in hash
$hash{$actual_portion}->{$next_portion}+=1;

} else { #there isn't transition in hash
my %row;
$hash{$next_portion}=$row;
while( my ($k, $v) = each %hash ) {
$row->{$k}=0;

}
$hash{$next_portion}=%row;

while ( my ($k, $v) = each %hash ){
$hash{$k}->{$next_portion}=0;
#if ($actual_portion ne $start_portion){
$hash{$start_portion}->{$next_portion}=0;}
}
$hash{$actual_portion}->{$next_portion}=1;
}
$i++;
$actual_portion=$next_portion;
}


return %hash;


}

I think that the problem is that I'm adding to the %hash the reference to %row instead of hash and when i'm changing value of field in row i'm changing value in all added rows. I tried to resolve that but I only get an errors. Can anybody know how to do this correct??

PS I'm sorry but my english isn't perfect.
 
Making your code a little more readable first gives us:

Code:
[url=http://perldoc.perl.org/functions/sub.html][black][b]sub[/b][/black][/url] [maroon]get_prob[/maroon] [red]{[/red]
	[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [red]([/red][blue]$file_content[/blue],[blue]$rank[/blue][red])[/red] = [blue]@_[/blue][red];[/red]
	[black][b]my[/b][/black] [blue]%hash[/blue][red];[/red]
	[black][b]my[/b][/black] [blue]%row[/blue][red];[/red]

	[blue]$start_portion[/blue] = [maroon]get_portion_of_string[/maroon][red]([/red][blue]$file_content[/blue],[fuchsia]0[/fuchsia],[blue]$rank[/blue][red])[/red][red];[/red]
	[blue]$actual_portion[/blue] = [blue]$start_portion[/blue][red];[/red]
	[blue]$hash[/blue][red]{[/red][blue]$actual_portion[/blue][red]}[/red]->[red]{[/red][blue]$actual_portion[/blue][red]}[/red] = [fuchsia]0[/fuchsia][red];[/red]

	[blue]$i[/blue]=[fuchsia]1[/fuchsia][red];[/red]
	[blue]$size[/blue] = [url=http://perldoc.perl.org/functions/length.html][black][b]length[/b][/black][/url][red]([/red][blue]$file_content[/blue][red])[/red][red];[/red]

	[olive][b]while[/b][/olive][red]([/red][blue]$i[/blue]+[blue]$rank[/blue] <= [blue]$size[/blue][red])[/red] [red]{[/red]
		[blue]$next_portion[/blue] = [url=http://perldoc.perl.org/functions/substr.html][black][b]substr[/b][/black][/url][red]([/red][blue]$actual_portion[/blue],[fuchsia]1[/fuchsia],[blue]$rank[/blue]-[fuchsia]1[/fuchsia][red])[/red][red];[/red]
		[blue]$next_portion[/blue] .= [black][b]substr[/b][/black][red]([/red][blue]$file_content[/blue],[blue]$i[/blue]+[blue]$rank[/blue]-[fuchsia]1[/fuchsia],[fuchsia]1[/fuchsia][red])[/red][red];[/red]

		[olive][b]if[/b][/olive] [red]([/red][url=http://perldoc.perl.org/functions/exists.html][black][b]exists[/b][/black][/url] [blue]$hash[/blue][red]{[/red][blue]$actual_portion[/blue][red]}[/red][red]{[/red][blue]$next_portion[/blue][red]}[/red][red])[/red] [red]{[/red]
			[gray][i]# there is transition in hash[/i][/gray]
			[blue]$hash[/blue][red]{[/red][blue]$actual_portion[/blue][red]}[/red]->[red]{[/red][blue]$next_portion[/blue][red]}[/red] += [fuchsia]1[/fuchsia][red];[/red]

		[red]}[/red] [olive][b]else[/b][/olive] [red]{[/red] [gray][i]#there isn't transition in hash[/i][/gray]
			[black][b]my[/b][/black] [blue]%row[/blue][red];[/red]
			[blue]$hash[/blue][red]{[/red][blue]$next_portion[/blue][red]}[/red] = [blue]$row[/blue][red];[/red]
			[olive][b]while[/b][/olive][red]([/red] [black][b]my[/b][/black] [red]([/red][blue]$k[/blue], [blue]$v[/blue][red])[/red] = [url=http://perldoc.perl.org/functions/each.html][black][b]each[/b][/black][/url] [blue]%hash[/blue] [red])[/red] [red]{[/red]
				[blue]$row[/blue]->[red]{[/red][blue]$k[/blue][red]}[/red]=[fuchsia]0[/fuchsia][red];[/red]
			[red]}[/red]
			
			[blue]$hash[/blue][red]{[/red][blue]$next_portion[/blue][red]}[/red] = [blue]%row[/blue][red];[/red]

			[olive][b]while[/b][/olive] [red]([/red] [black][b]my[/b][/black] [red]([/red][blue]$k[/blue], [blue]$v[/blue][red])[/red] = [black][b]each[/b][/black] [blue]%hash[/blue] [red])[/red] [red]{[/red]
				[blue]$hash[/blue][red]{[/red][blue]$k[/blue][red]}[/red]->[red]{[/red][blue]$next_portion[/blue][red]}[/red] = [fuchsia]0[/fuchsia][red];[/red]
				[gray][i]#if ($actual_portion ne $start_portion) {[/i][/gray]
				[gray][i]#	$hash{$start_portion}->{$next_portion}=0;[/i][/gray]
				[gray][i]#}[/i][/gray]
			[red]}[/red]
			[blue]$hash[/blue][red]{[/red][blue]$actual_portion[/blue][red]}[/red]->[red]{[/red][blue]$next_portion[/blue][red]}[/red] = [fuchsia]1[/fuchsia][red];[/red]
		[red]}[/red]
		[blue]$i[/blue]++[red];[/red]
		[blue]$actual_portion[/blue]=[blue]$next_portion[/blue][red];[/red]
	[red]}[/red]

	[url=http://perldoc.perl.org/functions/return.html][black][b]return[/b][/black][/url] [blue]%hash[/blue][red];[/red]
[red]}[/red]

There are some obvious problems starting around the second "my %row;" declaration. In the following 4 lines you interchangably refer to the hash %row and also the hash reference $row. This is most likely a bug.

Ultimately, the biggest thing that we can advise you to do us to "use strict;" and declare all your variables. This is always important, but even more so when dealing with complex data structures. It would point out obvious scoping problems such as using $row instead of %row as the former is not defined.

- Miller
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top