2

私はperlが初めてで、ディレクトリの距離を計算したいと思います。

以下に、ディレクトリの距離計算の例を示します。

このディレクトリのリストがあるとしましょう:

 abc/a.h                
 abc/clipboard/b.cc             
 abc/gfx/d.cc               
 abc/gfx/e.cc               
 abc/gfx/gl/f.cc                
 abc/gfx/gl/h.cc                
 abc/gfx/gl/tr/aq/i.cc

結果のテーブルは次のようになります。

       file1              |  file2                    |  Dir. distance
--------------------------+---------------------------+-----------------
     abc/a.h              |   abc/clipboard/b.cc      |  1
     abc/a.h              |   abc/gfx/d.cc            |  1
     abc/a.h              |   abc/gfx/e.cc            |  1
     abc/a.h              |   abc/gfx/gl/f.cc         |  2
     abc/a.h              |   abc/gfx/gl/h.cc         |  2
     abc/a.h              |   abc/gfx/gl/tr/aq/i.cc   |  4
     abc/clipboard/b.cc   |   abc/gfx/d.cc            |  2
     abc/clipboard/b.cc   |   abc/gfx/e.cc            |  2
     abc/clipboard/b.cc   |   abc/gfx/gl/f.cc         |  3
     abc/clipboard/b.cc   |   abc/gfx/gl/h.cc         |  3
     abc/clipboard/b.cc   |   abc/gfx/gl/tr/aq/i.cc   |  5
     abc/gfx/d.cc         |   abc/gfx/e.cc            |  0
     abc/gfx/d.cc         |   abc/gfx/gl/f.cc         |  1
     abc/gfx/d.cc         |   abc/gfx/gl/h.cc         |  1
     abc/gfx/d.cc         |   abc/gfx/gl/tr/aq/i.cc   |  3
     abc/gfx/e.cc         |   abc/gfx/gl/f.cc         |  1
     abc/gfx/e.cc         |   abc/gfx/gl/h.cc         |  1
     abc/gfx/e.cc         |   abc/gfx/gl/tr/aq/i.cc   |  3
     abc/gfx/gl/f.cc      |   abc/gfx/gl/h.cc         |  0
     abc/gfx/gl/f.cc      |   abc/gfx/gl/tr/aq/i.cc   |  2
     abc/gfx/gl/h.cc      |   abc/gfx/gl/tr/aq/i.cc   |  2

これは Perl を使用して実行できると思いますが、どのコード メソッドを使用すればよいかわかりません。

それを可能にするアプローチを知っている人はいますか?

よろしく、

4

3 に答える 3

1

sub distance始めるのに役立つはずです。Math::CombinatoricsnC2を使用して何度も呼び出すと、必要なものが得られます。

#!/usr/bin/perl 

use strict;
use warnings;

distance('abc/clipboard/b.cc','abc/gfx/gl/tr/aq/i.cc');#5

sub distance
{
    my ($path1,$path2)=@_;
    my @levels1=split(/\//,$path1);
    my @levels2=split(/\//,$path2);
    my $depth=0;
    for my $i (0..$#levels1)
    {
        if($levels1[$i] eq $levels2[$i])
        {
            $depth++;
        }
    }
    printf("$path1 $path2 %d\n",scalar(@levels1)+scalar(@levels2)-(2*$depth)-2);
}
于 2013-09-25T18:58:38.900 に答える
1

推奨アルゴリズム

ここでは、ツリー データ構造の観点からファイル パスを使用します。

  • A最初のパスのノードで構成されるセットを作成します
  • B2 番目のパスのノードで構成されるセットを作成します
  • それぞれのセットから両方のパスのリーフ ノードを削除します
  • との集合差を取りAますB。要するに、D = A diff B
  • の要素数はD、ツリー内の 2 つのパス間の距離を表します

Perl スクリプト

#!/usr/bin/perl
use warnings;
use strict;
use Array::Utils qw(:all);

my @dirs = (
                'abc/a.h',
                'abc/clipboard/b.cc',
                'abc/gfx/d.cc',
                'abc/gfx/e.cc',
                'abc/gfx/gl/f.cc',
                'abc/gfx/gl/h.cc',
                'abc/gfx/gl/tr/aq/i.cc'
            );

for (my $i=0; $i<@dirs-1; $i++) {
    my $d1 = $dirs[$i];
    for (my $j=$i+1; $j<@dirs; $j++) {
        my $d2 = $dirs[$j];
        # Set A of nodes in path 1 after discarding leaf node
        my @d1 = split '/', $d1; pop @d1;
        # Set B of nodes in path 2 after discarding leaf node
        my @d2 = split '/', $d2; pop @d2;
        # Set difference D = A diff B
        my @diff = array_diff(@d1, @d2);
        # No of elements in set D
        my $diff = @diff;
        # Print result in desired format
        print "$d1\t| $d2\t| $diff\n";
    }
}

出力

abc/a.h | abc/clipboard/b.cc    | 1
abc/a.h | abc/gfx/d.cc  | 1
abc/a.h | abc/gfx/e.cc  | 1
abc/a.h | abc/gfx/gl/f.cc   | 2
abc/a.h | abc/gfx/gl/h.cc   | 2
abc/a.h | abc/gfx/gl/tr/aq/i.cc | 4
abc/clipboard/b.cc  | abc/gfx/d.cc  | 2
abc/clipboard/b.cc  | abc/gfx/e.cc  | 2
abc/clipboard/b.cc  | abc/gfx/gl/f.cc   | 3
abc/clipboard/b.cc  | abc/gfx/gl/h.cc   | 3
abc/clipboard/b.cc  | abc/gfx/gl/tr/aq/i.cc | 5
abc/gfx/d.cc    | abc/gfx/e.cc  | 0
abc/gfx/d.cc    | abc/gfx/gl/f.cc   | 1
abc/gfx/d.cc    | abc/gfx/gl/h.cc   | 1
abc/gfx/d.cc    | abc/gfx/gl/tr/aq/i.cc | 3
abc/gfx/e.cc    | abc/gfx/gl/f.cc   | 1
abc/gfx/e.cc    | abc/gfx/gl/h.cc   | 1
abc/gfx/e.cc    | abc/gfx/gl/tr/aq/i.cc | 3
abc/gfx/gl/f.cc | abc/gfx/gl/h.cc   | 0
abc/gfx/gl/f.cc | abc/gfx/gl/tr/aq/i.cc | 2
abc/gfx/gl/h.cc | abc/gfx/gl/tr/aq/i.cc | 2
于 2013-09-25T18:59:28.910 に答える