获取数组中最小非负数的索引?

时间:2018-06-30 22:19:48

标签: perl

我有一个看起来像这样的数组

@array = ('3', '4', '71', '1', '-598', '-100203');

我想找到数组中整数中最小的非负数的索引。

在这种情况下:

  • 最小非负数= 1

  • 最小非负数的
  • 索引= 3

3 个答案:

答案 0 :(得分:5)

您要reduce(O(N)),而不是sort(O(N log N))!

use List::Util qw( reduce );

my $i =
   reduce { $array[$a] <= $array[$b] ? $a : $b }
      grep { $array[$_] >= 0 }
         0..$#array;

如果您想获得最佳性能,以下内容将使您更加接近:

use Config     qw( %Config );
use List::Util qw( minstr );

my $i =
   unpack "x$Config{ivsize} J",
      minstr
         map { pack 'J> J', $array[$_], $_ }
            grep { $array[$_] >= 0 }
               0..$#array;

答案 1 :(得分:1)

诀窍是对索引号列表进行排序,然后选择第一个:

my $ix = (sort { $array[$a]) <=> $array[$b] } grep { $array[$_] >= 0 } 0..$#array)[0];

答案 2 :(得分:-1)

最快的方法是扫描列表。

#!/usr/bin/env perl

# always use these two
use strict;
use warnings;

use feature qw( :all );

# --------------------------------------
#       Name: smallest_whole_number
#      Usage: ( $smallest, $index ) = smallest_whole_number( @array );
#    Purpose: Find the smallest whole number in an array.
# Parameters: @array -- array of integers
#    Returns: ( $smallest, $index ) unless exception.
#             ( -1, -1 ) if exception.
#
sub smallest_whole_number {
    my @array = @_;

    # check if array empty
    return ( -1, -1 ) unless @array;

    # scan for first whole number
    my $index = 0;
    while( $array[$index] < 0 ){

        # exception if no whole numbers in array
        return ( -1, -1 ) if $index >= $#array;

        $index ++;
    }

    # save first whole number found
    my $smallest = $array[$index];

    # scan the rest of the array
    for( my $i = $index + 1; $i <= $#array; $i ++ ){
        my $nbr = $array[$i];

        # skip negative numbers
        next if $nbr < 0;

        # check if current number smaller
        if( $smallest > $nbr ){
            $smallest = $nbr;
            $index    = $i;
        }
    }

    return ( $smallest, $index );
}

# --------------------------------------
# main

my @array = ('3', '4', '71', '1', '-598', '-100203');

my ( $smallest, $index ) = smallest_whole_number( @array );
say "smallest is $smallest at index $index";