Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Count similar characters in a row

by $new_guy (Acolyte)
on Oct 06, 2010 at 15:08 UTC ( [id://863806]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks,

I would like to count all the r's in the rows (row by row) then print to screen only the number of rows that have r's on all columns (i.e. 3 in this case). How do I do this. My script below doesn't seem to work well.

Thanks

script:

use strict; use warnings; # declare variables my @column = (); my $y; my %hash; my $count; my $range = 3; # open the file open(INFILE,"<","my_column_file.txt") or die("Couldn't open the file\n +"); while (<INFILE>) { print "\n"; #separate the elements in each row +with a newline for ($y=0; $y < 3; $y++){ # from the first to the last field + (ie field/column 3) my ($field) = (split)[$y]; # extract fields/ columns from the + data push @column, $field; # store all the field values in an + a array #count the consecutive r's --> all those common to a row #(i.e.if a sinlge specified column misses an r at that row do +n't cont it)! while ($field =~ /(r+)/g) { my $new_count = $count++; print "$new_count\n"; } print pop@column; # print from the array, each time r +emoving the printed element (avoiding repetition) print "\n"; # print each element in a new line } }

my file:

0 a b h 1 - r z 3 u - u 4 r x r 5 r t r 6 r r r 7 r r r 8 r r r

Replies are listed 'Best First'.
Re: Count similar characters in a row
by toolic (Bishop) on Oct 06, 2010 at 15:23 UTC
    use strict; use warnings; while (<DATA>) { my @cols = split; shift @cols; my $all_r = 1; for my $c (@cols) { if ($c ne 'r') { $all_r = 0; last; } } print if $all_r; } __DATA__ 0 a b h 1 - r z 3 u - u 4 r x r 5 r t r 6 r r r 7 r r r 8 r r r

    prints out:

    6 r r r 7 r r r 8 r r r

    update: even better with List::MoreUtils:

    use strict; use warnings; use List::MoreUtils qw(all); while (<DATA>) { my @cols = split; print if all { $_ eq 'r' } @cols[1 .. $#cols]; } __DATA__ 0 a b h 1 - r z 3 u - u 4 r x r 5 r t r 6 r r r 7 r r r 8 r r r
Re: Count similar characters in a row
by johngg (Canon) on Oct 06, 2010 at 17:44 UTC

    An alternative using tr (see Transliteration in Quote and Quote like Operators) to count the number of 'r's.

    knoppix@Microknoppix:~$ perl -E ' > open my $fh, q{<}, \ <<EOD or die $!; > 0 a b h > 1 - r z > 3 u - u > 4 r x r > 5 r t r > 6 r r r > 7 r r r > 8 r r r > EOD > > while ( <$fh> ) > { > my( $seq, @cols ) = split; > print if tr{r}{} == scalar @cols; > }' 6 r r r 7 r r r 8 r r r knoppix@Microknoppix:~$

    Cheers,

    JohnGG

      Thanks Monks,

      They all work well. However, except the perl one liners suggested no other scripts does what I wanted which in the end was to count the number ie 3 and print it on the screen!

      Also, how do I adapt the scripts to do this for a list (a second file - random.txt) separated by space as shown in the example below:

      2 3 2 3 2 1 2 1 3 2 1 3 3 3 1 3 1 2

      Notice there is a space in the first line. The numbers are clustered in the manner in which the r's common to all columns should be counted. For example print only the r's in column 2, then print all the r's common in all rows of column 3 and 2, then print the r's common to all rows in column 3 , 2 and 1.

      so the printed output for my file my_column_file.txt should below:

      0 a b h 1 - r z 3 u - u 4 r x r 5 r t r 6 r r r 7 r r r 8 r r r <p>should be:(the out put with explainations) </p> 4 3 3 (ie for 2 32 321) 4 5 3 (ie for 2 13 213) 5 5 3 (ie for 3 31 312) the out put desired 4 3 3 4 5 3 5 5 3

        Addressing your first issue is simple a matter of incrementing a count rather than printing the line.

        $ perl -Mstrict -wE ' > open my $fh, q{<}, \ <<EOD or die $!; > 0 a b h > 1 - r z > 3 u - u > 4 r x r > 5 r t r > 6 r r r > 7 r r r > 8 r r r > EOD > > my $count; > while ( <$fh> ) > { > my( $seq, @cols ) = split; > $count ++ if tr{r}{} == scalar @cols; > } > say $count;' 3 $

        The supplementary question requires a little more jiggery-pokery.

        $ perl -Mstrict -wE ' > open my $rand, q{<}, \ <<EOD or die $!; > 2 32 321 > 2 13 213 > 3 31 312 > EOD > > my @tests = > map [ split ], > <$rand>; > > open my $fh, q{<}, \ <<EOD or die $!; > 0 a b h > 1 - r z > 3 u - u > 4 r x r > 5 r t r > 6 r r r > 7 r r r > 8 r r r > EOD > > my @results; > while ( <$fh> ) > { > my @cols = split; > foreach my $idx ( 0 .. $#tests ) > { > foreach my $subidx ( 0 .. $#{ $tests[ $idx ] } ) > { > my @posns = split m{}, $tests[ $idx ]->[ $subidx ]; > $results[ $idx ]->[ $subidx ] ++ > if scalar @posns == grep { q{r} eq $cols[ $_ ] } @pos +ns; > } > } > } > > say qq{@$_} for @results;' 4 3 3 4 5 3 5 5 3

        I hope this is useful.

        Cheers,

        JohnGG

Re: Count similar characters in a row
by suhailck (Friar) on Oct 06, 2010 at 15:26 UTC
    Try this,

    perl -wle 'while(<>) { $count++ if "rrr" eq join "",(split)[1 .. 3] }; print $count' my_column_file.txt 3
      perl -lane '$count++ if "rrr" eq join "",@F[1 .. 3] }{ print $count' m +y_column_file.txt
Re: Count similar characters in a row
by jwkrahn (Abbot) on Oct 06, 2010 at 15:30 UTC
    # open the file open INFILE, '<', 'my_column_file.txt' or die "Couldn't open 'my_colum +n_file.txt' $!"; while ( <INFILE> ) { my ( $row_num, @fields ) = split; print if @fields == grep /r/, @fields; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://863806]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-19 05:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found