Search code examples
arraysperlparentheses

Getting indices of matching parentheses


Hi I am trying to print indices of the following pattern of brackets:

((((((...)))(((...))))))

as follows:

0 23
1 22
2 21
3 11
4 10
5 9
12 20
13 19
14 18

I tried to achieve this using this perl code as given below:

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

my $string = '((((((...)))(((...))))))';
my @myarray = split('', $string); 
my @stack;
my @stack1;



while (my ($index, $element) = each(@myarray))
{

   if ($element eq '(')
   {
   push(@stack, $index);  
   }

   if ($element eq ')')
   {
   push(@stack1, $index);  
   }  
}


print "$stack[$_]-$stack1[$_]\n" for (0 .. $#stack);

But the above code is giving me following output which is not the required output:

0-9
1-10
2-11
3-18
4-19
5-20
12-21
13-22
14-23

Is there any way I can achieve this?


Solution

  • Push to the stack on the left hand side parenthesis, pop on the right hand side.

    #!/usr/bin/perl
    use warnings;
    use strict;
    use feature qw{ say };
    
    my $string = '((((((...)))(((...))))))';
    
    my @output;
    my @stack;
    
    my $pos = 0;
    for my $char (split //, $string) {
        if ($char eq '(') {
            push @stack, $pos;
        } elsif ($char eq ')') {
            push @output, [ pop @stack, $pos ];
        }
        ++$pos;
    }
    say "@$_" for sort { $a->[0] <=> $b->[0] } @output;