Я пытаюсь перевести сценарий Perl в PHP, и я испытываю затруднения из-за некоторых вещей Perl. Например, что делает @_ -1
средний? И как я пишу это в PHP?
Целая функция следующие:
sub variance {
my $sum = sum_squares (@_);
my $deg = @_ - 1;
return $sum/$deg;
}
Хорошо, все подпрограммы следующие:
sub mean { # mean of values in an array
my $sum = 0 ;
foreach my $x (@_) {
$sum += $x ;
}
return $sum/@_ ;
}
sub sum_squares { # sum of square differences from the mean
my $mean = mean (@_) ;
my $sum_squares = 0 ;
foreach my $x (@_) {
$sum_squares += ($x - $mean) ** 2 ;
}
return $sum_squares ;
}
sub variance { # variance of values in an array
my $sum_squares = sum_squares (@_) ;
my $deg_freedom = @_ - 1 ;
return $sum_squares/$deg_freedom ;
}
sub median { # median of values in an array
my @sorted = sort {$a <=> $b} (@_) ;
if (1 == @sorted % 2) # Odd number of elements
{return $sorted[($#sorted)/2]}
else # Even number of elements
{return ($sorted[($#sorted-1)/2]+$sorted[($#sorted+1)/2]) / 2}
}
sub histogram { # Counts of elements in an array
my %histogram = () ;
foreach my $value (@_) {$histogram{$value}++}
return (%histogram) ;
}
Терпите меня потому что в его мой первый раз с Perl. Из того, что я видел (протестированный), правильный ответ в этом случае является тем David Dorward. У меня действительно есть другой вопрос относительно этого набора подпрограмм, который является здесь.
В этом случае @_
- это аргументы, переданные подпрограмме в виде списка.
В скалярном контексте это количество элементов в этом списке.
Итак, если вы вызываете: variance ('a', 'b', 'c', 'd');
, $ deg
будет 3.
Как уже было сказано, это массив аргументов, переданных функции. В PHP это эквивалентно
func_get_args ()
- возвращает массив, содержащий список аргументов функции func_num_args ()
- возвращает количество аргументов, переданных функции Вся функция будет be
function variance() {
$sum = sum_squares(func_get_args());
$deg = func_num_args() - 1;
return $sum/$deg;
}
// echo variance(1,2,3,4,5); // 13.75 (55/4)
Для sum_squares
в PHP нет собственной функции. Предполагая, что он делает то, что подразумевает название, например возводя каждый аргумент в степень 2 и затем суммируя результат, вы можете реализовать это как
function sum_squares(array $args) {
return array_reduce(
$args, create_function('$x, $y', 'return $x+$y*$y;'), 0
);
}
// echo sum_squares( array(1,2,3,4,5) ); // 55
Заменить create_function
на правильную лямбду , если вы используете PHP5.3
Это количество аргументов, переданных подпрограмме дисперсии
минус один (или индекс последнего элемента в @ _
массив). @_
здесь используется в скалярном контексте.
@_
- это список параметров, передаваемых в подпрограмму. Когда вы используете его в нескалярном контексте, таком как:
sum_squares (@_)
, вы получаете список, поэтому, по-видимому, он вернет сумму квадратов всех чисел в этом списке (однако см. Комментарий ниже).
При использовании в скалярном контексте вы получаете длину, поэтому в вашем случае это будет количество элементов в списке функций $ @
.
Итак, ваша функция дисперсии, вероятно (я говорю, вероятно, поскольку у меня нет доступа к исходному коду sum_squares
), вычисляет:
variance = arr[0]^2 + arr[1]^2 + ... + arr[N-1]^2
--------------------------------------
N - 1
на массиве значений, передаваемых в вашу функцию.
Я должен сказать, что мое понимание дисперсии расходится с этим (хотя я давно не делал никаких статистических данных). Я почти уверен, что он должен включать сумму квадратов различий между значениями и средним значением, не самих значений. Я подозреваю, что внутри sum_squares
происходит больше, чем следует из его простого названия.
В дополнение к другим ответам специальная переменная @_
описана в бесплатной официальной онлайн-документации Perl (вместе с другие переменные):
Внутри подпрограммы массив @_ содержит параметры, переданные этой подпрограмме. См. Perlsub.
@_ - параметр, входящий в подпрограмму, но в скалярном контексте указывается количество параметров.
В php будет что-то вроде:
function variance() {
$arguments = func_get_args();
$sum = sum_squares($arguments);
$deg = sizeof($arguments);
return $sum/$deg;
}
В функции @_ будет список аргументов функции, которые передаются в функцию. На самом деле, когда мы пытаемся присвоить значение списка скаляру, он присваивает длину массива. Здесь -1 для доступа к последнему элементу массива @_
sub test { my $count = @_ ; # Now it will assign the number of function arguments # Because we are trying to assign as a scalar. >print "Output:$count\n" ; # Output : 4 ($count ) = @_ # Now it will assign the first element of the functions print "Output:$count\n" ; # OUtput: 10 # Because we are trying to assign as list values , So ,list as only one variable . # So , first element gets assigned. } &test ( 10,20,30,40 ) ;