2013-02-28 62 views
10

Tôi mới dùng perl và tìm giá trị thấp nhất trong một @array. Có một số hằng số đại diện cho một số nguyên rất lớn không?Tương đương perl của MAX_INT là bao nhiêu?

Tôi biết tôi có thể sắp xếp mảng và bắt đầu, nhưng dường như có rất nhiều chu kỳ CPU bị lãng phí. Một giải pháp thanh lịch cho vấn đề của tôi trong Perl là gì?

+0

Đây có thể là tốt nhất để sắp xếp. Sắp xếp là 'O (n log n)'. Khi so sánh với đi qua ('O (n)'), nó chỉ là vấn đề nếu bạn có mảng với hàng nghìn đến hàng triệu mục. –

+0

Tôi không thích câu trả lời đó. Perl có phải là ngôn ngữ SLOW không? Chắc chắn là không. Phải có một giải pháp thanh lịch hơn. Không có giá trị MAX?!? – Zak

+0

Perl sử dụng nội bộ * Sắp xếp nhanh *, do đó tôi đoán trường hợp xấu nhất sẽ vẫn là 'O (n log n)'. –

Trả lời

18

Trong trường hợp chung, bạn có thể sử dụng undef để báo hiệu giá trị không tồn tại; perl vô hướng không bị giới hạn để giữ chỉ số nguyên. Điều đó sẽ được viết:

my $min; # undef by default 
for my $value (@array) { 
    $min = $value if !defined $min or $value < $min; 
} 

Nhưng có một số tùy chọn đơn giản hơn tại đây. Ví dụ, khởi $min với giá trị đầu tiên trong mảng, sau đó so sánh với phần còn lại:

my $min = $array[0]; 
for my $i (1 .. $#array) { 
    $min = $array[$i] if $array[$i] < $min; 
} 

Hoặc chỉ cần sử dụng một hàm built-in:

use List::Util 'min'; 
my $min = min @array; 
+3

+1 cho Danh sách :: Util :: min() gợi ý. –

+0

Cảm ơn bạn đã trả lời rất tuyệt vời và kỹ lưỡng! +1 – Zak

+1

Lưu ý rằng cả ba trả về cùng một kết quả cho một mảng trống ('undef')! – ikegami

-2

Giá trị số nguyên lớn nhất perl có thể lưu trữ là 9,007,199,254,740,992

Tôi không biết liệu có liên tục cụ thể cho điều đó hay không.

+0

Không! Tôi lưu trữ điều này trong biến, và tiếp tục tăng lên, và nó hoạt động! –

+0

Điều này là bán đúng cho 32-bit perl (2^53 là số nhỏ nhất bạn có thể lưu trữ trong phao tiêu chuẩn chính xác gấp đôi để x và x + 1 không phân biệt được) và chắc chắn sai cho perl 64 bit. – hobbs

2

9**9**9 công trình. Vì vậy, không 0+'inf' trên nhiều phiên bản/nền tảng của perl.

2

Perl không phải là C; nếu bạn cố gắng tính toán một số nguyên quá lớn, bạn sẽ nhận được kết quả dấu phẩy động thay thế (trừ khi bạn use bigint, làm cho số nguyên không bị chặn). Ngoài ra, bạn nhận được inf.

Bạn có thể thấy điều này với Devel::Peek, trong đó cho thấy bạn trình bày nội Perl của một giá trị:

$ perl -E 'use Devel::Peek; Dump(1000); Dump(1000**100); Dump(1000**100 + 1)' 
SV = IV(0xcdf290) at 0xcdf2a0 
    REFCNT = 1 
    FLAGS = (PADTMP,IOK,READONLY,pIOK) 
    IV = 1000 
SV = NV(0xd04f20) at 0xcdf258 
    REFCNT = 1 
    FLAGS = (PADTMP,NOK,READONLY,pNOK) 
    NV = 1e+300 
SV = NV(0xd04f18) at 0xcdf228 
    REFCNT = 1 
    FLAGS = (PADTMP,NOK,READONLY,pNOK) 
    NV = 1e+300 

IV chỉ ra một giá trị số nguyên; NV cho biết giá trị dấu phẩy động (Số?).

Bạn chắc chắn nên sử dụng một công cụ phù hợp với mục đích của bạn thay vì hack mờ; List::Util::min như đã đề cập trong câu trả lời khác là tuyệt vời. Chỉ cần nghĩ bạn có thể muốn xác nhận về câu hỏi của bạn ban đầu :)

+1

yeah," N "là viết tắt của con số. Ngoài ra còn có UV cho số nguyên unsigned. – ikegami

17

Để trả lời cho bạn những câu hỏi mà bạn thực sự yêu cầu (mặc dù nó không thực sự sử dụng cho bạn):

  1. giá trị số nguyên lớn nhất có thể được lưu trữ dưới dạng số nguyên đã ký.

    say ~0 >> 1; 
    
  2. Giá trị nguyên lớn nhất có thể được lưu trữ dưới dạng số nguyên không dấu.

    say ~0; 
    
  3. Tất cả giá trị nguyên từ 0 đến số này có thể được lưu trữ mà không bị mất dưới dạng số dấu phẩy động.

    Lưu ý rằng một số số nguyên lớn hơn có thể được lưu trữ mà không bị mất số dấu phẩy động, chứ không phải số 1 cao hơn số này.

+0

qw() làm gì? – Zak

+0

@Zak, [perlop] (http://perldoc.perl.org/perlop.html). Tìm kiếm "' qw/STRING/'". – ikegami

+0

Cảm ơn! Liên kết tuyệt vời. – Zak

Các vấn đề liên quan