2010-07-20 10 views
6

Tôi muốn sử dụng chức năng pack() trong Perl để mã hóa một số dữ liệu. Sau đó, tôi muốn so sánh cấu trúc đóng gói của tôi với một cấu trúc đóng gói khác. Tôi muốn so sánh này là trên các giá trị byte của cấu trúc được đóng gói này.Làm cách nào để so sánh các giá trị được đóng gói trong Perl?

Theo tài liệu, cmp sử dụng ngôn ngữ hiện tại để xác định cách so sánh chuỗi. Nhưng tôi không muốn bất kỳ thông minh nào được áp dụng cho so sánh. Tôi muốn bất cứ điều gì là gần nhất với một memcmp(). Rõ ràng tôi không thể sử dụng <=> để so sánh các đối tượng đóng gói của tôi vì chúng không phải là số.

Cách tốt nhất để so sánh chuỗi được đóng gói trong Perl là gì?

Sidenote: Tôi đã đọc this article on efficient sorting in Perl lưu ý rằng hàm sắp xếp đơn giản sử dụng thuật toán giống như memcmp để so sánh cấu trúc. Tôi tự hỏi làm thế nào để đạt được một so sánh như vậy mà không cần phải sử dụng sắp xếp.

+1

'sort' thực sự là một nơi tuyệt vời để bắt đầu từ đâu. Việc cố gắng xây dựng bộ phận thay thế sắp xếp của riêng bạn có thể sẽ không hoạt động tốt như bạn muốn, vì loại Perl đã được tinh chỉnh trong nhiều năm. Liên kết phân loại hiệu quả mà bạn đưa ra thực sự bao gồm các hướng dẫn về cách sử dụng cấu trúc dữ liệu đóng gói để tăng tốc độ sắp xếp, khá thông minh, nhưng việc phân loại sẽ phải mất một thời gian dài trước khi tôi cống hiến bản thân để duy trì điều đó. – sarnold

+0

Bạn có muốn so sánh (tức là, nhỏ hơn, lớn hơn hoặc bằng) hoặc kiểm tra bình đẳng có hoặc không? –

+0

@gbacon: Tôi muốn thứ gì đó tôi có thể đặt hàng, ít hơn, lớn hơn, bằng. –

Trả lời

5

cân nhắc Disable locale cho khối và sử dụng cmp như thường lệ:

sub mycmp { 
    no locale; 
    $_[0] cmp $_[1]; 
} 

Các tài liệu perlop cung cấp

lt, le, ge, gtcmp sử dụng collation (loại) thứ tự được chỉ định bởi ngôn ngữ hiện tại nếu use locale có hiệu lực. Xem perllocale.

và sau đó trong perllocale

Hành vi mặc định được khôi phục cùng với no locale pragma, hoặc khi đến cuối khối kèm use locale.

Ví dụ, chạy

my($one,$two) = map pack("N", $_) => 1, 2; 
say mycmp($one, $two); 
say mycmp($two, $one); 

đầu ra

-1 
1
+0

"Không miền địa phương" chỉ áp dụng trong phạm vi đóng cửa? Nếu có một miền địa phương áp dụng bên ngoài việc đóng cửa, nó vẫn sẽ áp dụng cho bất kỳ mã nào dưới sự đóng cửa? –

+0

@PP Vâng, pragma 'locale' là từ vựng: nó chỉ có hiệu lực bên trong khối kèm theo của nó. –

0

Suy nghĩ to ở đây - các nhà khai thác bitwise có giúp được không? Cũng giống như làm một xor trên hai chuỗi giống hệt nhau sẽ cho một bitstring với tất cả mọi thứ thiết lập để 0.

http://perldoc.perl.org/perlop.html#Bitwise-String-Operators

+0

xor sẽ là một thử nghiệm bình đẳng tuyệt vời độc lập với ngôn ngữ, thực sự - ý tưởng hay - sẽ không hữu ích cho ít hơn/lớn hơn tuy nhiên. –

4

Expand, then contract. Hãy so sánh ví dụ đại diện hex của cấu trúc của bạn, mà chỉ sử dụng các ký tự ASCII và không thể đụng chạm tới miền địa phương vấn đề bạn đề cập đến.

unpack('H*', $first) cmp unpack('H*', $second)