2013-11-02 4 views
1

Я новичок в perl, и у меня есть проблема, которую я пытаюсь решить. На этом этапе в моей программе я поместил файл в массив и создал хеш, где все ключи - это числа, которые увеличиваются на определенный пользователем размер буфера, в пределах диапазона. Значения всех ключей равны 0. Моя цель это цикл через массив и найти числа, которые соответствуют ключам моего хэша, и увеличивать соответствующее значение на 1 в случае совпадения. Для того, чтобы найти конкретное значение в массиве немного проще, каждая строка массива будет содержать только один ряд интересов, и это число будет ВСЕГДА быть десятичным, поэтому, возможно, я могу использовать регулярное выражение:Perl: Looping через массив для увеличения значений хеша

=~ m{(\d+\.\d+)} 

выбрать интересующие их цифры. После нахождения интересующего числа мне нужно округлить число (в тот момент, когда я использую «Math :: Round» nlowmult '; »), чтобы он мог попасть в соответствующий ящик (если он существует), и если bin не существует, цикл должен продолжаться до тех пор, пока не будут проверены все строки массива.

Таким образом, общая цель состоит в том, чтобы иметь хэш, который имеет запись о количестве раз, которое появляются в этом массиве, в пределах указанного пользователем диапазона и приращения (размер буфера).

В минуту мой код пытается это (MathRound был назван ранее в программе):

my $msline; 
foreach $msline (@msfile) { 

    chomp $msline; 
    my ($name, $pnum, $m2c, $charge, $missed, $sequence) = split (" ", $msline); 

    if ($m2c =~ /[$lowerbound,$upperbound]/) { 

     nlowmult ($binsize, $m2c); 
     $hash{$m2c}++; 

    } 

} 

Примечание: каждая строка массива содержит 6 полей, с числом интерес всегда появляющейся в третье поле «m2c».

Программа не округляет значения вниз, не добавляет значения к клавишам, создает новые ключи и увеличивает их. Я также не думаю, что использование split - хорошая идея, так как реальный массив будет содержать около 40 000 строк. Это может привести к тому, что процесс популяции хеширования будет очень медленным.

Куда я иду не так? Может ли кто-нибудь дать мне какие-либо советы относительно того, как я могу решить эту проблему? Если какие-либо аспекты проблемы нуждаются в дальнейшем разъяснении, дайте мне знать!

Спасибо заранее!

+0

Если у меня нет ответа, я попробую это, спасибо :) – user2941526

+1

Что вы пытаетесь сделать с '$ m2c = ~/[$ lowerbound, $ upperbound] /'? Это регулярное выражение, которое соответствует любому из символов в строках '$ lowerbound',' $ upperbound' или запятой. Он не проводит численное тестирование диапазона. – Barmar

+0

С этим выражением я пытаюсь только захватить значения в пределах диапазона, указанного пользователем, и игнорировать любые, которые выходят за пределы диапазона – user2941526

ответ

1

Изменение:

if ($m2c =~ /[$lowerbound,$upperbound]/) { 

    nlowmult ($binsize, $m2c); 
    $hash{$m2c}++; 

} 

к:

if ($m2c >= $lowerbound && $m2c <= $upperbound) { 

    $m2c = nlowmult ($binsize, $m2c); 
    $hash{$m2c}++; 

} 

Вы не можете использовать регулярные выражения, как, что для проверки числовых диапазонов. И вы используете исходное значение $m2c как хэш-ключ, а не округленное значение.

+0

Решил мою проблему, большое спасибо :) – user2941526

1

Я думаю, что главная проблема заключается ваша линия:

nlowmult ($binsize, $m2c); 

Изменение этой строки в:

$m2c = nlowmult ($binsize, $m2c); 

бы решить хотя бы эту проблему, потому что nlowmult() фактически не изменять $m2c. Он просто возвращает округленный результат. Вам нужно сообщить perl, чтобы сохранить этот результат обратно в $m2c.

Вы можете объединить эту строку и один под ней, если вы не хотите, чтобы на самом деле изменить содержимое $m2c:

$hash{nlowmult ($binsize, $m2c)}++; 

, вероятно, не соперничают ответ, но я надеюсь, что помогает.

+0

Это очень помогло, спасибо за ваше ответ :) – user2941526

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