2017-02-19 11 views
0

Я пытаюсь выполнить задачу, которую я сделал на другом языке программирования, но Perl кажется немного другим, и я боюсь.Аргумент не является числовым

Мне нужно создать базовую базу данных, и эта база данных должна содержать строки в соответствии с их первой буквой.

Например, когда я даю этот вход: SQL AHT NFK IOS C64 SQL AHT END

Нужный результат будет:

A – E: AHT C64 
F – J: IOS 
K – O: NFK 
P – T: SQL 
U – Z: 

Но когда я даю, например, AAA BBB END, я получаю тонны ошибок и все из них очень похожи:

Argument "AAA" isn't numeric in addition (+) at proje.pl line 76 <STDIN> line 3. 

Я помещаю весь код, потому что я не имею ни малейшего представления, что является причиной этой ошибки. Я проверил другие вопросы, но я не очень помог мне.

use warnings; 

    sub doesExistInDatabase { 

    my ($abbreviation) = @_; 
    my @database = @_; 
    my $boolean = 0;  

    for(my $c = 1; $c < 20; $c++){ 
     for(my $d = 0; $d < 5; $d++){ 
      if($database[$c][$d] eq ($abbreviation)){ 
       $boolean = 1; 
      } 
     } 
    } 
    return $boolean; 
} 

    $database[0][0] = "A-E"; 
    $database[0][1] = "F-J"; 
    $database[0][2] = "K-O"; 
    $database[0][3] = "P-T"; 
    $database[0][4] = "U-Z"; 

    for(my $i = 1; $i < 20; $i++){ 
     for(my $k = 0; $k < 5; $k++){ 
      $database[$i][$k] = ""; 
     } 
    } 

    @numberOfElements = (0,0,0,0,0);  

     while($numberOfElements[0] < 20 and $numberOfElements[1] < 20 and $numberOfElements[2] < 20 
      and $numberOfElements[3] < 20 and $numberOfElements[4] < 20){ 

      my $abbreviation = <STDIN>; 
      chomp($abbreviation); 
      my @chars = split //, $abbreviation; 

      my $existing = doesExistInDatabase($abbreviation, @database); 


      if($abbreviation eq "END"){ 
       last; 
      } 

      if($existing == 0){ 
       if($chars[0] eq "A" or $chars[0] eq "B" or $chars[0] eq "C" or 
         $chars[0] eq "D" or $chars[0] eq "E"){ 
        $numberOfElements[0]++; 
        $database[$numberOfElements[0]][0] = $abbreviation; 
       } 
       if($chars[0] eq "F" or $chars[0] eq "G" or $chars[0] eq "H" or 
         $chars[0] eq "I" or $chars[0] eq "J"){ 
        $numberOfElements[1]++; 
        $database[$numberOfElements[1]][0] = $abbreviation; 
       } 
       if($chars[0] eq "K" or $chars[0] eq "L" or $chars[0] eq "M" or 
         $chars[0] eq "N" or $chars[0] eq "O"){ 
        $numberOfElements[2]++; 
        $database[$numberOfElements[2]][0] = $abbreviation; 
       } 
       if($chars[0] eq "P" or $chars[0] eq "Q" or $chars[0] eq "R" or 
         $chars[0] eq "S" or $chars[0] eq "T"){ 
        $numberOfElements[3]++; 
        $database[$numberOfElements[3]][0] = $abbreviation; 
       } 
       if($chars[0] eq "U" or $chars[0] eq "V" or $chars[0] eq "W" or 
         $chars[0] eq "X" or $chars[0] eq "Y" or $chars[0] eq "Z"){ 
        $numberOfElements[4]++; 
        $database[$numberOfElements[4]][0] = $abbreviation; 
       } 
      } 
    } 
    print("\n$database[0][0]: "); 
    for(my $x = 1; $x < $numberOfElements[0]+1; $x++){ 
     printf(" " + $database[$x][0]); 
    } 
    print("\n$database[0][1]: "); 
    for(my $x = 1; $x < $numberOfElements[0]+1; $x++){ 
     printf(" " + $database[$x][1]); 
    } 
    print("\n$database[0][2]: "); 
    for(my $x = 1; $x < $numberOfElements[0]+1; $x++){ 
     printf(" " + $database[$x][2]); 
    } 
    print("\n$database[0][3]: "); 
    for(my $x = 1; $x < $numberOfElements[0]+1; $x++){ 
     printf(" " + $database[$x][3]); 
    } 
    print("\n$database[0][4]: "); 
    for(my $x = 1; $x < $numberOfElements[0]+1; $x++){ 
     printf(" " + $database[$x][4]); 
    } 
+4

Вы должны начать все файлы Perl с 'использовать строгие; используйте предупреждения, чтобы автоматически найти множество распространенных проблем. – melpomene

+1

Не используйте 'printf', где' print' достаточно. В частности, у вас должна быть очень хорошая причина использовать 'printf' с непостоянной строкой формата. – melpomene

+1

Оператор '+' добавляет два числа. – melpomene

ответ

2

Вы можете сделать ваш код намного более читаемым и избежать этих многомерных массивов и циклов C-типа одновременно. Простое сравнение stringwise все, что нужно для того, чтобы просеивать свои условия в ведро:

use strict; 
use warnings; 

use Data::Dump; 

sub bucketize { 
    my %buckets = (
     'A-E' => {}, 
     'F-J' => {}, 
     'K-O' => {}, 
     'P-T' => {}, 
     'U-Z' => {}, 
    ); 

    for my $term (@_) {  
     for my $bucket (reverse(sort(keys(%buckets)))) { 
      if ($term gt $bucket) { 
       $buckets{$bucket}{$term}++; 
       last; 
      } 
     } 
    } 

    return \%buckets; 
} 

my $hash_ref = bucketize(qw(SQL AHT NFK IOS C64 SQL AHT)); 
dd($hash_ref); 

Выход:

{ 
    "A-E" => { AHT => 2, C64 => 1 }, 
    "F-J" => { IOS => 1 }, 
    "K-O" => { NFK => 1 }, 
    "P-T" => { SQL => 2 }, 
    "U-Z" => {}, 
} 
0

В perl оператор для конкатенации строк есть. (Период) не + (плюс), которые вы использовали:

printf(" " + $database[$x][0]) 

Должно быть:

printf(" " . $database[$x][0]) 

Или просто:

print " $database[$x][0]" 

Если у вас есть больше знаний о Perl, может быть, вы 'll хотите взглянуть на это решение:

my(@group,%group) = qw(A-E F-J K-O P-T U-Z); 
while(<>){ 
    my $abbr=$_; chomp($abbr); 
    $group{$_}{$abbr}++ for grep $abbr=~/^[$_]/i, @group; 
} 
print "$_: ".join(" ",sort keys %{$group{$_}})."\n" for @group; 

Тест:

for i in SQL AHT NFK IOS C64 SQL AHT END AAA BBB END PERL;do echo $i;done|perl program.pl 
A-E: AAA AHT BBB C64 END 
F-J: IOS 
K-O: NFK 
P-T: PERL SQL 
U-Z: 

 Смежные вопросы

  • Нет связанных вопросов^_^