$array can't print anything - perl

This is my program , I want to let user type a matrix line by line and print the while matrix , but I can't see the matrix
The user will type
1 2 3
4 5 6
7 8 9
like this
and I want to let it show
1 2 3
4 5 6
7 8 9
Perl program
$Num = 3;
while($Num > 0 )
{
$Row = <STDIN>;
$Row = chomp($Row);
#Row_array = split(" ",$Row);
push #P_matrix , #Row_array;
#Row_array = ();
$Num = $Num - 1;
}
for($i=0;$i<scalar(#P_matrix);$i++)
{
for($j=0;$j<scalar(#P_matrix[$i]);$j++)
{
printf "$d ",$P_matrix[$i][$j];
}
print "\n";
}
I change the expression => printf "$d ",$P_matrix[$i][$j]; to print $P_matrix[$i][$j]
but still don't work.

To create a multi-dimensional array, you have to use references. Use
push #P_matrix, [ #Row_array ];
to create the desired structure.
Also, chomp does not return the modified string. Simply use
chomp $Row;
to remove a newline from $Row. Moreover, chomp is not needed at all if you split on ' '.
printf uses % as the formatting character, not $.
You can use Data::Dumper to inspect complex data structures. Use strict and warnings to help you avoid common problems. Here is how I would write your program:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my #p_matrix;
push #p_matrix , [ split ' ' ] while <>;
warn Dumper \#p_matrix;
for my $i (0 .. $#p_matrix)
{
for my $j (0 .. $#{ $p_matrix[$i] })
{
printf '%d ', $p_matrix[$i][$j];
}
print "\n";
}

First and foremost please use use strict; use warnings;
Issues in your code:
You have a single dimensional array, but your are trying to access
it like two dimensional array. In order to make 2 dimensional array push the array reference of Row_array in #P_matrix as [#Row_array].
Where is $d defined? declare $d as my $d or our $d if you mean $d as scalar variable.
OR
For using %d, use need sprintf. Please read this.

Related

How to find the number of vowels in a string using Perl

sub Solution{
my $n=$_[0];
my $m=lc $_[1];
my #chars=split("",$m);
my $result=0;
my #vowels=("a","e","i","o","u");
#OUTPUT [uncomment & modify if required]
for(my $i=0;$i<$n;$i=$i+1){
for(my $j=0;$j<5;$j=$j+1){
if($chars[$i]==$vowels[$j]){
$result=$result+1;
last;
}
}
}
print $result;
}
#INPUT [uncomment & modify if required]
my $n=<STDIN>;chomp($n);
my $m=<STDIN>;chomp($m);
Solution($n,$m);
So I wrote this solution to find the number of vowels in a string. $n is the length of the string and $m is the string.
However, for the input 3 nam I always get the input as 3.
Can someone help me debug it?
== compares numbers. eq compares strings. So instead of $chars[$i]==$vowels[$j] you should write $chars[$i] eq $vowels[$j]. If you had used use warnings;, which is recommended, you'd have gotten a warning about that.
And by the way, there's no need to work with extra variables for the length. You can get the length of a string with length() and of an array for example with scalar(). Also, the last index of an array #a can be accessed with $#a. Or you can use foreach to iterate over all elements of an array.
A better solution is using a tr operator which, in scalar context, returns the number of replacements:
perl -le 'for ( #ARGV ) { $_ = lc $_; $n = tr/aeiouy//; print "$_: $n"; }' Use Perl to count how many vowels are in each string
use: 2
perl: 1
to: 1
count: 2
how: 1
many: 2
vowels: 2
are: 2
in: 1
each: 2
string: 1
I included also y, which is sometimes a vowel, see: https://simple.wikipedia.org/wiki/Vowel
Let me suggest a better approach to count letters in a text
#!/usr/bin/env perl
#
# vim: ai:ts=4:sw=4
#
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $debug = 0; # debug flag
my %count;
my #vowels = qw/a e i o u/;
map{
chomp;
my #chars = split '';
map{ $count{$_}++ } #chars;
} <DATA>;
say Dumper(\%count) if $debug;
foreach my $vowel (#vowels) {
say "$vowel: $count{$vowel}";
}
__DATA__
So I wrote this solution to find the number of vowels in a string. $n is the length of the string and $m is the string. However, for the input 3 nam I always get the input as 3.
Can someone help me debug it?
Output
a: 7
e: 18
i: 12
o: 12
u: 5
Your code is slightly modified form
#!/usr/bin/env perl
#
# vim: ai:ts=4:sw=4
#
use strict;
use warnings;
use feature 'say';
my $input = get_input('Please enter sentence:');
say "Counted vowels: " . solution($input);
sub get_input {
my $prompt = shift;
my $input;
say $prompt;
$input = <STDIN>;
chomp($input);
return $input;
}
sub solution{
my $str = lc shift;
my #chars=split('',$str);
my $count=0;
my #vowels=qw/a e i o u/;
map{
my $c=$_;
map{ $count++ if $c eq $_} #vowels;
} #chars;
return $count;
}

perl user input into a data structure

I am trying to take user input such as 4 2 1 4 and store that into an array. Then loop through the array looking for duplicates to store into a hash table.
#!/usr/bin/perl -w
print "Enter numbers into hash table :";
my #num = <STDIN>;
my %hash;
foreach $x (#num){
my $count =1;
foreach $y(#num){
if($x == $y){
my $count++;
$hash{'$x'} = $count;
}
}
}
map{print "$_\t$hash{$_}\n"}keys %hash;
I expect the result to be:
1 1
2 1
4 2
The actual result, I just continue to enter digits, after I hit enter the program continues to ask for more input. I hit CTRL D and nothing happens.
There are a great many problems with your code and I don't have time to explore them all
I hope it helps to offer you a working solution
#!/usr/bin/perl
use strict;
use warnings 'all';
my %counts;
print "Enter numbers into counts table: ";
++$counts{$_} for split ' ', <STDIN>;
print "$_\t$counts{$_}\n" for keys %counts;
output
E:\Perl\source>count.pl
Enter numbers into counts table: 4 2 1 4
1 1
2 1
4 2
Probably it is possible to do more nicely, but i would do this as:
use strict;
use warnings;
use Data::Dumper;
my $numbers;
print "Enter numbers and finish with CTRL-D\n";
while(my $line = <STDIN>) {
$numbers->{$_}++ for ( $line =~ m/(\b\d+\b)/g );
}
print Dumper $numbers;

Perl: iterating values in for loop

print "Input value \n";
$line = <>;
chomp $line;
#val = $line;
for ($i = 1; $i <= 10; $i++){
print -#val* $i;
}
I have a simple for loop here where the user enters a value that I store into the #val, and I want my loop to iterate from 1 to 10 and print out the value of -#val * $i. Suppose my #val = 2, then I should see the output: -2 -4 -6 - 8 ... -20. But my actual output is: -1 -2 ... -10. What went wrong?
As I wrote in my comment, I can't imagine what you were trying to achieve by copying the value of $line to array #val. There are also a number of other points that I would like to make
You must always
use strict;
use warnings 'all';
at the start of all your Perl programs. You will then have to declare all of your variables with my, and it will alert you to many simple errors that you may otherwise overlook
The C-style for loop is rarely useful in Perl. It is usually best to iterate over a simple list. In your program that would be
for my $i ( 1 .. 10 ) {
...
}
So putting all that together, your program looks like this
use strict;
use warnings 'all';
print "Input value\n";
my $val = <>;
chomp $val;
for my $i ( 1 .. 10 ) {
print -$val * $i;
}
It's also worth pointing out that, when the contents of the for loop is just a single statement like this, you can use for as a statement modifier and write just
print -$val * $_ for 1 .. 10;
The problem is that you're storing your value in an array (#val). When you use that array in a scalar context (the math in the for loop) you just get the number of elements in the array. In your case 1. Change #val to $val or just use $line directly.

How to create dynamic arrays in perl

I have a situation where input is in form of
$n followed by n lines having elements of n different arrays.
like
2
1 2 3
1 6
means i have 2 arrays with elements as 1,2,3 and 1,6.
Now i really dont know how big N can be. How to create dynamic arrays and store value to them. Arrays may be named array1,array2 or any other method to differentiate different arrays.
$n = <STDIN>;
for ($i = 0; $i < $n; $i++) {
$l = <STDIN>;
#arr = split(" ", $l);
}
Please improve this code.
You can use an array of arrays:
use strict;
my #array;
while(<STDIN>) {
my #line = split(" ", $_);
push #array, \#line;
}
# Just to display what's inside your array:
use Data::Dumper;
print Dumper(\#array);
Or even shorter:
use strict;
my #array;
push #array, [split ' ', $_] while(<STDIN>);

Perl multidimensional array question

I have a program that prints out the location of commas in a paragraph of text in the form
For example if the paragraph is
one,two,three
three and a half
four,five
six
seven,eight
The program will print
0:4
0:8
2:5
4:6
I would like to use this output to create an array where the numbers after the colon are listed across columns in the row specified by the index before the colon. The array formed by the coordinates above would be
4 8
<blank or character '.'>
5
<blank or character '.'>
6
so array[0,0] = 4, array[0,1] = 8
array[1,0] = empty
array[2,0] = 5
etc...
I bet this is simple but I need help to write it.
$data_file="file.out";
open(DAT, $data_file) || die("Could not open file!");
#raw_data=<DAT>;
close(DAT);
my %array;
my $line = 0;
foreach $newline(#raw_data) {
chomp;
while ( $newline=~m/(,|;|:|and)/) {
push #{ $array{$line} }, pos($newline); # autovivification
}
$line++; }
Program
#!/usr/bin/env perl
use strict;
use warnings;
my %array;
my $line = 0;
while (<DATA>) {
chomp;
while ( /(,|;|:|(?:and))/g ) {
my $position = pos() - length($1) + 1;
push #{ $array{$line} }, $position; # autovivification
}
$line++;
}
for ( sort { $a <=> $b } keys %array ) {
my $flattened_value = join ', ', #{ $array{$_} };
print "$_ -> $flattened_value\n";
}
__DATA__
one,two,three
three and a half
four,five
six
seven,eight
Output
0 -> 4, 8
1 -> 7
2 -> 5
4 -> 6
Refer: chomp, join, keys, sort, split.
Refer the following documents to get an understanding of Perl's data structures and especially autovivification which has been used in this example.
perldoc perlref
perldoc perlreftut