您所在的位置: 首页>>开发>>语言&工具>>

perl的建树算法

http://developer.51cto.com  2005-09-09 11:08  RobinKin  RobinKin 的 Blog  我要评论(0)
  • 摘要:本文是关于perl的建树算法的详细代码
  • 标签:Perl
=pod
=item
  @result=();
$ldap_root="NTA::ou1";
push @result,"NTA::ou1::ou2::ou3";
push @result,"NTA::ou1::ou2::ou4";
  push @result,"NTA::ou1::ou5::ou6";
push @result,"NTA::ou1::ou5::ou6::o8";
push @result,"NTA::ou1::ou5::ou6::o9";

push @result,"NTA::ou1::ou5::ou7";
push @result,"NTA::ou1::ou5::ou7::t";
push @result,"NTA::ou1::ou5::ou7::t::y";
push @result,"NTA::ou1::ou5::ou7::t::y::u";
  push @result,"NTA::ou1::ou6::ou8";
push @result,"NTA::ou1::ou6::ou8::ji";
push @result,"NTA::ou1::ou6::ou8::ji::jk";
push @result,"NTA::ou1::ou6::ou9::j";
push @result,"NTA::ou1::ou6::ou9::g";
=cut
########################################################
sub recusive_ldap{
my %param=@_;
my $left_list =$param{left_list}; # a array to put the left string in,use @$ to use it
my $left =$param{left};
my $right =$param{right},
my $r_ldap_array=$param{r_ldap_array}; # use $$ to use this ref
my $r_rid =$param{r_rid}; #use $$ to use it
my $prefix =$param{prefix};

FIND_DIFF:
 my @found=();
 my $current_group;
 my @merge_list=();

my $diff_group_idx=-1;

my $found_new_group=0;#begin a new match
my $matched_new_group=0;
my $begin_match=0;
my ($left_idx,$right_idx);
 my $blank_item=0;

CURR: for(my $i=$left;$i<$right;$i++){
  if( @$left_list[$i] ne ''){
@$left_list[$i]=~/::/;
$current_group=$';
   if($current_group=~/::/){
$current_group=$`;
   }
  }

else{#last node  impossible to be a father nodwa
$current_group=undef;
$blank_item++;
  next CURR; # get next item
}

if (scalar @found== 0){ #first item
   if(defined $current_group){
$begin_match=1;
push @found ,$current_group  ;
$diff_group_idx++;
$left_idx=$i ;

if(  (scalar @found ==1)  &&   ($i==$right-1)  ){
my $merge={};
$merge->{left}=$left+$blank_item;
$merge->{right}=$i+1;
push @merge_list,$merge;#storage the merge of the current node
}
   }
next CURR;
  }

else { #matched a group and meet a new grp
   if($current_group ne $found[$diff_group_idx]){# a new node

push @found ,$current_group;
    $left_idx=$i if $begin_match;
    $begin_match=0;
$diff_group_idx++;
$right_idx=$i;


if(scalar @found==2){
     my $merge={};
$merge->{left}=$left+$blank_item;
$merge->{right}=$i;
push @merge_list,$merge;#storage the merge of the current node

}
else{
my $merge={};
$merge->{left}=$left_idx;
$merge->{right}=$i;
push @merge_list,$merge;#storage the merge of the current node


}
    if ($i==$right-1){ #last match
my $merge={};
if(scalar @found >1){
$merge->{left}=$right_idx;
}
else {
$merge->{left}=$left+$blank_item;

}
$merge->{right}=$i+1;
push @merge_list,$merge;#storage the merge of the current node
    }
 
    $left_idx=$i;
   }
   else{ # continue to match the same father node
if ($i==$right-1){ #last matcha
my $merge={};

if(scalar @found ==1){
$merge->{left}=$left+$blank_item;
}
else{
$merge->{left}=$right_idx;
}

$merge->{right}=$i+1;
push @merge_list,$merge;#storage the merge of the current node

}
}
 
 
  }
}# find all grps(different)
 return if scalar @found==0;
my $rid=0;
my $blank=[];
my $current;
my @g_array;
# print Dumper $left_list;
# print Dumper \@merge_list;
CREATE_NODE:
for(my $diff_grp=0;$diff_grp<scalar  @found; $diff_grp++){ #every different node
  my @ldgArray=();
  my $cur_grp=$found[$diff_grp];
   my $reg="::".$cur_grp;
   $reg=reg_encode($reg);
  for(my  $gidx=$merge_list[$diff_grp]->{left};
$gidx<$merge_list[$diff_grp]->{right}; $gidx++){

@$left_list[$gidx] =~s/^$reg//;# stript out this item
}

my $new_prefix= $prefix.$cur_grp."::";
  my $new_cap= $prefix.$cur_grp;
  if( $merge_list[$diff_grp]->{left}== $merge_list[$diff_grp]->{right}){
my $item=_creat_node('gx_l'.$$r_rid,$cur_grp,0,1,'','edit_group.cgi?name='.$new_cap."&m_i=gxl_$$r_rid");
$$r_rid++;
   push @$r_ldap_array,$item; # put the new node to the container
  }
else{

&recusive_ldap(
left_list =>$left_list,
left  =>$merge_list[$diff_grp]->{left} ,
right  =>$merge_list[$diff_grp]->{right},
r_ldap_array =>\@ldgArray,
r_rid  =>$r_rid,
prefix  =>$new_prefix
);
   my $item=_creat_node('gx_l'.$$r_rid,$cur_grp,1,1,\@ldgArray,'edit_group.cgi?name='.$new_cap."&m_i=gxl_$$r_rid");

$$r_rid++;
   push @$r_ldap_array,$item; # put the new node to the container
}
 } 
};
 
############################################################################################
sub _creat_node{ #create a node of a menu tree
my $node={};

# print "add";
#essential field
#$node->{'name'}=Translate shift;
$node->{'name'}=shift;
$node->{'info'}->{'text'}=shift;
#info field
$node->{'info'}->{'isparent'}=shift;
$node->{'info'}->{'linkout'}=shift;
#extra field
#if  is parent this field shouldn't be ''
# this parameter can be a single node or an array of node
$node->{'children'}=shift;# default a ref to array

#if  the menu linkout this field shouldn't be blank
$node->{'info'}->{'url'}=shift;

if ($node->{'children'} ne ''){
  if((ref $node->{'children'}) ne "ARRAY"){ # it's a hash ref
my @ar;
push @ar, $node->{'children'};
$node->{'children'}=\@ar;
}
else{
}
}
else{ #if a blank is pass to a 'children' field delete this field
delete $node->{'children'};
}
 return $node;
}
1;

Perl应用教程
走向银光 —— 一步一步学Silverlight2
让你的代码“炫”起来——WPF开发教程
WebSphere 实现SOA的利器
初探敏捷开发
 
 验证码: (点击刷新验证码)   匿名发表
  • Visual C++ 6.0完全自学宝典

  • 作者:强锋科技,朱洪波
  • Visual C++ 6.0是微软公司为程序人员提供的Visual Studio 6.0工具套件中的重要组成部分。本书由浅入深地介绍使用Visual C++ 6.0..
Copyright©2005-2008 51CTO.COM 版权所有