http://qs1969.pair.com?node_id=1108671

rsFalse has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I tried to make a primitive subroutine, which could match some two-dimensional set of characters.

And my questions are: 1) have you used two-dimensional search and where? 2) what are good approaches of making match more affective and more fast?

I've find similar, but old node Two-dimensional match/regex?, almost all links there are non-working.

Below is my try.
My example search is:
# # #.
And subroutine searches all occurrences of such combination of these 4 chars.
In usual one-dimension search matches can not overlap if we use /g modifier and do not change pos(), but here I'm changing pos() and matches can overlap.
use warnings; use strict; sub two_d_search{ my $amount_of_data = shift; my @data = splice @_, 0, $amount_of_data; my @pattern = (); my ($arg, $indentation, $string); my $i = 0; while (@_){ $arg = shift; if ($arg eq "\n"){ $i++; $arg = shift; } $indentation = $arg; $string = shift; $pattern[ $i ] .= ".{$indentation}" if $indentation; $pattern[ $i ] .= $string; print "($i: $pattern[ $i ])", "\n"; } my $pos; my $match = 0; my @matches = (); for my $i (0 .. @data - 1){ undef pos $data[ $i ]; OUT_2: while ($data[ $i ] =~ m/$pattern[0]/g){ ($pos) = @-; # matches can overlap, so 'pos' increases only by +1: (pos $data[ $i ]) = $pos + 1; for my $j (1 .. @pattern - 1){ pos ($data[ $i + $j ]) = $pos; if ($data[ $i + $j ] =~ m/\G$pattern[$j]/){ # do nothing } else { next OUT_2 } } $match ++; push @matches, "[row: $i|column: $pos]"; } } $" = "\n"; # set list output separator to "\n" return "Number of matches: $match;", "Upper-left corners match at:\n@matches" } my @data = <DATA>; chomp @data; my @info = &two_d_search( scalar @data, @data, # indentation; string; argument of line separation 1, '#', "\n", # two_d_regex first line 0, '#', "\n", # two_d_regex second line 2, '#\.' # two_d_regex third line ); print "@info",$/; __DATA__ #..#.....#. ..#...##... .#....#..## #..#....#.. ..#...#..#. .......#.#. ...........
http://ideone.com/O1j7vp
OUTPUT: (0: .{1}#) (1: #) (2: .{2}#\.) Number of matches: 3; Upper-left corners match at: [row: 1|column: 1] [row: 1|column: 6] [row: 2|column: 0]
I think that speed complexity of this search is slow, maybe O(size_of_data * size_of_search_pattern).