#!/usr/bin/perl -w use strict; sub diff4 { my $strings = shift; my %start_set_by_l_token; my %l_by_start; my %l_by_end; { my %start_set_by_token; my $I = 0; for my $s (@$strings) { my $sl = length $s; for (my $i=0; $i<$sl; ++$i) { my $start = "${I}_$i"; my $substr = substr $s, $i, 1; $start_set_by_token{$substr}{$start} = 1; } $I++; } while (my ($substr, $start_set) = each %start_set_by_token) { if (keys %$start_set == 1) { delete $start_set_by_token{$substr} } else { for my $start (keys %$start_set) { my ($I, $i) = split /_/, $start, 2; $l_by_start{$start} = 1; $l_by_end{$I."_".($i+$l)} = 1; } } } $start_set_by_l_token{1} = \%start_set_by_token; } my @start_sorted = map {$_->[0]} sort { $a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] } map {[$_, split /_/, $_]} keys %l_by_start; for my $start (@start_sorted) { my ($I, $i) = split /_/, $start, 2; my $can_join_start if ($l_by_end{$start}) { } } my $l; for ($l=2; ; ++$l) { my %start_set_by_token; my $I = 0; while (my ($substr, $start_set) = each %{$start_set_by_l_token{$l-1}}) { for my $start (keys %$start_set) { my ($I, $i) = split /_/, $start, 2; my $s = $$strings[$I]; my $sl = length $s; if ($i <= $sl-$l) { my $substr = substr $s, $i, $l; $start_set_by_token{$substr}{$start} = 1; } } } while (my ($substr, $start_set) = each %start_set_by_token) { delete $start_set_by_token{$substr} if keys %$start_set == 1; } last if keys %start_set_by_token == 0; $start_set_by_l_token{$l} = \%start_set_by_token; } my $n = $l; }