2011-06-03 49 views
6

Tôi bị mắc kẹt với những gì trông giống như một vấn đề khái niệm đơn giản với tôi. Sau khi siêng năng tìm kiếm các vấn đề tương tự trên Web và Stack Overflow tôi không thể tìm thấy một cái gì đó tương tự, vì vậy tôi nghĩ rằng tôi có thể hỏi bạn.Làm cách nào để đệ quy đi bộ cấu trúc dữ liệu băm lồng nhau?

Tôi đang tạo mã băm băm cấu trúc dữ liệu được lồng sâu. Độ sâu có thể là 10-20 lần. Vì lợi ích của vấn đề này tôi chỉ liệt kê cho đến độ sâu một.

Tôi không thể đệ quy đi qua mẫu băm bên dưới trong Perl. Tôi cũng đã bao gồm mã của tôi.

Nó mang lại cho tôi những lỗi sau:

Can't use string ("1") as a HASH ref while "strict refs" in use at

Chỉ cần để nó là rõ ràng: băm của tôi chắc chắn sẽ có một số phím có giá trị 1. Tôi không thể tránh chúng.

$VAR1 = { 
    'Eukaryota' => { 
     'Rhodophyta'   => {'count' => 5}, 
     'Alveolata'   => {'count' => 16}, 
     'stramenopiles'  => {'count' => 57}, 
     'count'    => 155, 
     'Glaucocystophyceae' => {'count' => 1}, 
     'Cryptophyta'  => {'count' => 18}, 
     'Malawimonadidae' => {'count' => 1}, 
     'Viridiplantae'  => {'count' => 57}, 
    }, 
    'Bacteria' => { 
     'Cyanobacteria'  => {'count' => 1}, 
     'Actinobacteria'  => {'count' => 4}, 
     'count'    => 33, 
     'Proteobacteria'  => {'count' => 25}, 
     'Deinococcus-Thermus' => {'count' => 2}, 
     'Firmicutes'   => {'count' => 1}, 
    }, 
}; 

Mã để đệ quy đi băm này:

sub analyse_contig_tree_recursively { 
    my $TAXA_TREE = shift @_; 
    my $contig_hash = shift @_; 
    foreach (keys %{$TAXA_TREE}) { 
     print "$_ \n"; 
     analyse_contig_tree_recursively($TAXA_LEVEL->{$_}, $contig_hash); 
    } 
} 

Trả lời

11

Tôi không chắc chắn những gì bạn đang gọi điện thoại analyse_contig_tree_recursively trên (bạn không sử dụng mà $contig_hash tham số bất cứ nơi nào, và bạn chưa xác định $TAXA_LEVEL: ý của bạn là $TAXA_TREE?), Nhưng rõ ràng là không khớp giữa bố cục cấu trúc dữ liệu của bạn và mẫu truyền tải đệ quy của bạn. Chức năng traversal của bạn giả định rằng tất cả các mục là băm, và xử lý các băm rỗng như trường hợp chấm dứt: nếu keys %{$TAXA_TREE} trống, không có cuộc gọi đệ quy nào. Với dữ liệu của bạn, bạn cần phải kiểm tra xem một giá trị có phải là băm hay không, và không tái kiểm tra nếu bạn thấy nó không phải là một băm.

sub analyse_contig_tree_recursively { 
    my $TAXA_TREE   = shift @_; 
    foreach (keys %{$TAXA_TREE}){ 
     print "$_ \n"; 
     if (ref $TAXA_TREE->{$_} eq 'HASH') { 
      analyse_contig_tree_recursively($TAXA_TREE->{$_}); 
     } 
    } 
} 
+4

hoặc 'Scalar :: Util :: reftype ($ TAXA_TREE -> {$ _}) eq 'HASH'', nếu cấu trúc dữ liệu có thể chứa các đối tượng may mắn. – mob

+0

@Giles: Cảm ơn một loạt. Nó dint tấn công với tôi rằng có những phím trong băm của tôi mà không trỏ đến tham chiếu băm và có thể báo hiệu kết thúc đệ quy. Về $ TAXA_LEVEL, $ contig_hash: đó chỉ là một số biến khác mà tôi sử dụng để xử lý. Vấn đề chính là rõ ràng bây giờ và chương trình của tôi hoạt động ... Các bạn nhanh chóng và tuyệt vời .. Cảm ơn một bó – Abhi

+0

Con người, các bạn nhanh chóng. Trong trường hợp bạn chỉ đơn giản muốn xem cấu trúc của bạn và không nhất thiết phải làm bất cứ điều gì với nó, hãy sử dụng [Data :: Dumper] (http://perldoc.perl.org/Data/Dumper.html). BTW, khi bạn nhận được vào băm của băm hoặc danh sách băm, hoặc danh sách các băm của danh sách, vv, đó là thời gian để bắt đầu suy nghĩ về lập trình hướng đối tượng. Mất thêm vài phút để thiết lập, nhưng có thể giúp bạn tiết kiệm rất nhiều nỗi đau khi gỡ lỗi sau này. Tôi đề nghị nó ngay cả đối với một giao dịch bắn. –

Các vấn đề liên quan