Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1327267
  • 博文数量: 268
  • 博客积分: 10698
  • 博客等级: 上将
  • 技术积分: 2867
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-14 22:21
文章分类

全部博文(268)

文章存档

2012年(19)

2011年(13)

2010年(29)

2009年(26)

2008年(99)

2007年(82)

我的朋友

分类:

2008-07-13 03:02:55


#!/usr/bin/perl -w
# Program name : sch3.pl
# Written by Myst Shen
# version 2.1, Aug.6, 2008
#

use strict;
use Term::ANSIColor;

my ($count, $maxlen, %options, @all_ofs, @all_ofs1, @all_ofs2, @all_ofs3, @orderly_ofs, @same_line_ofs, $x);

%options = (
    "-a" => sub {$x = 0},
    "-b" => sub {$x = 1},
    "-c" => sub {$x = -1},
    "-h" => \&help,
    "-v" => \&version,
)
;

sub help {
    print "usage: sch3.pl [option] [string] file\n";
    print "options:\n";
    print "\t-a\tsearch vertically\n";
    print "\t-b\tsearch slantly from left to right\n";
    print "\t-c\tsearch slantly from right to left\n";
    print "\t-h\thelp\n";
    print "\t-v\tversion\n";

    exit 0;
}

sub version {
    print "sch3.pl version 2.1\n";
    exit
0;
}

getopts (\@ARGV, \%options );
sub getopts{
    my ($arg, $op);
    my ($ARG, $OP) = @_;
    foreach $arg (@$ARG) {
        if (exists $OP ->{$arg}) {
        $op = $OP->{$arg};
        &$op();
        }
    }
}

# get the maximum length of lines

sub max_len {
    open(DATA, "$ARGV[2]") or die $!;
    $maxlen = 0;
    while (<DATA>){
        s/\s+$//;
        $maxlen = length if (length > $maxlen);
    }
    return $maxlen;
}

# count the lines

sub line_num {
    seek DATA,0,0;
    my $count1 = 0;
    my $count2 = 0;
    while (<DATA>) {
        $count1 ++;
        if (/^\s*$/) {
            $count2 ++;
        } else {
            $count2 = 0;
        }
    }
    $count = $count1 - $count2;
    return $count;
}

# search the string

sub vertical {
    my (@indices1);
    max_len;
    line_num;
    for (my $i=0;$i<$maxlen;$i++) {
        my $str1 = " ";
        my $str2 = "";
        seek DATA,0,0;
        while (<DATA>) {
            $_ .= " "x($maxlen - length($_)) if (length($_) < $maxlen);
            $str1 = substr($_,$i,1);
            $str2 .= $str1;
        }
    my $pos = 0;
    while ($pos<length($str2)){
        my $idx = index($str2,$ARGV[1],$pos);
        last if ($idx == -1);
        push (@indices1, "$i,$idx");
        $pos += $idx +1;
        }
    }

    # prepare the letters to be colorized

    foreach my $i (@indices1) {
        push (@all_ofs1, $i);
        my $i2 = $i;
        $i =~ s/(.*),(.*)/$1/;
        $i2 =~ s/(.*),(.*)/$2/;
        for (my $p=1; $p<length($ARGV[1]); $p++) {
            $i2 ++;
            push (@all_ofs1,"$i,$i2");
            }
        }
    return @all_ofs1;
}

sub slant {
    my (@indices2, $y, $idx2, $idx3);
    max_len;
    line_num;
    if ($x == -1) {
        $y = -1;
    }
    elsif ($x == 1) {
        $y = 0;
    }
    for (my $i=0;$i<$maxlen;$i++) {
        my $str1 = " ";
        my $str2 = "";
        my $j = $i;
        seek DATA,0,0;
        while (<DATA>) {
            $_ .= " "x($maxlen - length($_)) if (length($_) < $maxlen);
            $str1 = substr($_,$j*$x+$y,1);
            $str2 .= $str1;
            last if ($j == $maxlen -1);
            $j ++;
        }
        my $pos = 0;
        while ($pos<length($str2)){
            my $idx = index ($str2, $ARGV[1], $pos);
            if ($x == -1) {
                $idx2 = $maxlen - $idx - $i;
            }
            elsif ($x == 1) {
                $idx2 = $i + $idx;
            }
            last if ($idx == -1);
            push (@indices2, "$idx2,$idx");
            $pos += $idx +1;
        }
    }

    for (my $i=1;$i<=$count-2;$i++) {
        my $str1 = " ";
        my $str2 = "";
        my $j = 0;
        my $num = 0;
        seek DATA,0,0;
        while (<DATA>) {
            $_ .= " "x($maxlen - length($_)) if (length($_) < $maxlen);
            $num ++;
            next if ($num <= $i);
            $str1 = substr($_,$j*$x+$y,1);
            $str2 .= $str1;
            $j ++;
        }
        my $pos = 0;
        while ($pos<length($str2)) {
            my $idx = index ($str2, $ARGV[1], $pos);
            if ($x == -1) {
                $idx3 = $maxlen - $idx;
            }
            elsif ($x == 1) {
                $idx3 = $idx;
            }
            my $idx2 = $i + $idx;
            last if ($idx == -1);
            push (@indices2, "$idx3,$idx2");
            $pos += $idx +1;
        }
    }

    # prepare the letters to be colorized

    foreach my $i (@indices2) {
        push (@all_ofs2, $i);
        my $i2 = $i;
        $i =~ s/(.*),(.*)/$1/;
        $i2 =~ s/(.*),(.*)/$2/;
        for (my $p=1; $p<length($ARGV[1]); $p++) {
            if ($x == -1) {
                $i --;
            }
            elsif ($x == 1) {
                $i ++;
            }
            $i2 ++;
            push (@all_ofs2,"$i,$i2");
        }
    }
    return @all_ofs2;
}

# options

if ($x == 0) {
    vertical;
} else {
    slant;
}

# sort the offsets

sub by_order {
    my @aa = split (/,/,$a);
    my @bb = split (/,/,$b);
    return ($aa[0] <=> $bb[0]);
}

L: for my $p (@all_ofs1) {
    for my $q (@all_ofs2) {
        next L if ($q eq $p);
    }
    push (@all_ofs3, $p);
}
@all_ofs = (@all_ofs3, @all_ofs2);
for (my $j=0;$j<$count;$j++) {
    undef @same_line_ofs;
    @all_ofs2 = @all_ofs;
    foreach my $i (@all_ofs2) {
        my $i2 = $i;
        $i =~ s/(.*),(.*)/$1/;
        $i2 =~ s/(.*),(.*)/$2/;
        push (@same_line_ofs, "$i,$i2") if ($i2 == $j);
    }
    my @ofs_sorted = sort by_order @same_line_ofs;
    @orderly_ofs =(@orderly_ofs, @ofs_sorted);
}

# print

seek DATA,0,0;
my $line_num = 0;
while (<DATA>) {
    my $matches_num = 0;
    my $ofs = 0;
    my @orderly_ofs2 = @orderly_ofs;
    foreach my $i (@orderly_ofs2) {
        my $i2 = $i;
        $i =~ s/(.*),(.*)/$1/;
        $i2 =~ s/(.*),(.*)/$2/;
        if ($line_num == $i2) {
            $matches_num ++;
            print color 'reset';
            print substr($_, $ofs, $i-$ofs);
            print color 'red';
            print substr($_, $i, 1);
            $ofs = $i+1;
        }
    }
    if ($matches_num != 0) {
        print color 'reset';
        print substr($_, $ofs);
    } else {
        print color 'reset';
        print;
    }
    $line_num ++;
}

close(DATA);


#./sch3.pl -a ABC data_file
1C1A3A443A3
A89BB3B3BB7
BB4A4BAC8A6
C3BA87B7BB3
A12BB8C66A6
9B3CBA29BBI
390A40B3333
98B288BU3B8
0C340384394
08A373737A3
1B8BA828B82
333BC33C333

#./sch3.pl -b ABC data_file
1C1A3A443A3
A89BB3B3BB7
BB4A4BAC8A6
C3BA87B7BB3
A12BB8C66A6
9B3CBA29BBI
390A40B3333
98B288BU3B8
0C340384394
08A373737A3
1B8BA828B82
333BC33C333

#./sch3.pl -c ABC data_file
1C1A3A443A3
A89BB3B3BB7
BB4A4BAC8A6
C3BA87B7BB3
A12BB8C66A6
9B3CBA29BBI
390A40B3333
98B288BU3B8
0C340384394
08A373737A3
1B8BA828B82
333BC33C333
阅读(937) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~