3

Perlを使用して、各リストの繰り返し(重複)値のみを出力したいと思います。値は少なくとも2回(2回以上)表示される必要があります。各リスト(行)は個別に検討する必要があります。

たとえば、次の入力があります。

abc 51082 6457 31072 5575 5488 4842 16567 151

cde 5575 3674 8150  5575 3674 8150

fgh 5737 6887 48278 3674 34399 3674 8150

次の出力が必要です。

abc 
cde 5575 3674 8150
fgh 3674

次のソースコードを書きましたが、正しい出力が得られません。

#!/usr/bin/perl -w

open FH, "input.txt";
@a=<FH>;

my %count_of;

foreach $tmp (@a) 
{
    foreach $word (split /\s/, $tmp) 
    {
        $count_of{$word}++;

        if ($count_of{$word} >=2)
        {
            print "$word\n";
        }
    }
}

exit;

誰かがコードにどのような変更を加える必要があるかについて教えてもらえますか?ありがとうございました!

4

3 に答える 3

1

ここに作業バージョンがあります。コード内のコメントを見て、修正を理解してください

#!/usr/bin/perl

# always use strict and warnings: this will help you to find errors
use warnings;
use strict;

open FH, 'input.txt';

# always declare variables
my @a=<FH>;

# you should close file handles
close FH;

# declare $tmp
foreach my $tmp (@a) {

    # you need to process the first element differently since you
    # want to always print it
    my @row = split /\s/, $tmp;

    # you should check for empty rows
    if (@row == 0) {
        # empty row
        next;
    }

    # removes the first element
    my $header = shift @row;

    # the first element is always printed
    print $header;

    # this should be local otherwise you are counting globally
    # a new declaration will give you a new hash
    my %count_of;

    # declare $word
    foreach my $word ( @row ) {

        # you should not increment an undefined variable
        if ( $count_of{$word} ) {
            $count_of{$word} = 1;
        } else {
            $count_of{$word}++;
        }

        # just print the second time you see the word
        if ( $count_of{$word} == 2) {
            print " $word";
        }

    }

    print "\n";

}

# it is good practice to return true at the end of a script (no need to exit)
1;

これにより、次のものが生成されます。

abc
cde 5575 3674 8150
fgh 3674
于 2012-05-31T06:37:18.583 に答える
1

grep表示された値を追跡するためのハッシュと組み合わせることは、これらの種類の問題に適しています。

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

my $file = "input.txt";
open my $fh, "<", "$file" or die "Unable to open $file: $!\n";

while (<$fh>) {
    chomp;
    my ($key, @values) = split or next; # skip empty rows
    my (%seen, @dupl);
    @dupl = grep $seen{$_}++ == 1, @values;
    print "$key @dupl\n";
}

出力:

abc 
cde 5575 3674 8150
fgh 3674

or(ではなく||)両方の条件で重要であることに注意してください。さらに、ファイルを開こうとした結果を常に確認する必要があります。移植性のためにuse strict;、できればに置き換え-wてください。use warnings;とにかくファイルを1行ずつ処理する場合は、ファイルを丸呑みにする必要もありません。

于 2012-05-31T06:56:33.590 に答える
0
#!/usr/bin/perl -w

use strict;

while (<>) {
    chomp;
    my ($name, @inp) = split /\s+/ or next;
    my %counts;
    for (@inp) { $counts{$_}++ }
    print join (' ', $name, map { $counts{$_} > 1 ? $_ : () } keys %counts), "\n";
}
于 2012-05-31T06:50:15.640 に答える