Cách dễ nhất để lấy khóa có giá trị cao nhất từ băm trong Perl là gì?Cách dễ nhất để lấy chìa khóa có giá trị cao nhất từ băm trong Perl là gì?
Trả lời
Trong khi các giải pháp với sắp xếp:
(sort {$hash{$a} <=> $hash{$b}} keys %hash)[0]
tìm thấy trong một số các câu trả lời khác là khá thanh lịch, nó không hoạt động như độc đáo vì nó trông. Trước hết, sắp xếp biến đổi hoạt động tìm kiếm tìm kiếm O(n)
thành một số O(n log n)
. Thứ hai, giải pháp sắp xếp có số lần xem băm n log n
. Hash look-up rất tốt cho các hoạt động nhất định, nhưng khi làm việc với toàn bộ băm, tra cứu sẽ chậm hơn sử dụng each
, keys
hoặc values
để lặp qua cấu trúc dữ liệu. Điều này là do các trình vòng lặp không cần tính toán các băm khóa, cũng như chúng không cần phải lặp đi lặp lại thông qua các thùng để tìm các giá trị. Và chi phí không phải là không đổi, nhưng tăng khi băm trở nên lớn hơn.
Dưới đây là một số giải pháp nhanh hơn:
use strict;
use warnings;
my %hash = (
small => 1,
medium => 5,
largest => 10,
large => 8,
tiny => 0.1,
);
Đây là một giải pháp sử dụng các each
iterator (một hoạt động O(1)
làm n
lần):
sub largest_value (\%) {
my $hash = shift;
keys %$hash; # reset the each iterator
my ($large_key, $large_val) = each %$hash;
while (my ($key, $val) = each %$hash) {
if ($val > $large_val) {
$large_val = $val;
$large_key = $key;
}
}
$large_key
}
print largest_value %hash; # prints 'largest'
Hoặc một phiên bản nhanh hơn trao đổi mua bán bộ nhớ cho tốc độ (nó tạo một bản sao của băm):
sub largest_value_mem (\%) {
my $hash = shift;
my ($key, @keys) = keys %$hash;
my ($big, @vals) = values %$hash;
for (0 .. $#keys) {
if ($vals[$_] > $big) {
$big = $vals[$_];
$key = $keys[$_];
}
}
$key
}
print largest_value_mem %hash; # prints 'largest'
Đây là hiệu suất với các kích cỡ khác nhau băm:
10 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 111565/s -- -8% -13%
largest_value 121743/s 9% -- -5%
largest_value_mem 127783/s 15% 5% --
50 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 24912/s -- -37% -40%
largest_value 39361/s 58% -- -6%
largest_value_mem 41810/s 68% 6% --
100 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 9894/s -- -50% -56%
largest_value 19680/s 99% -- -12%
largest_value_mem 22371/s 126% 14% --
1,000 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 668/s -- -69% -71%
largest_value 2183/s 227% -- -7%
largest_value_mem 2341/s 250% 7% --
10,000 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 46.5/s -- -79% -81%
largest_value 216/s 365% -- -11%
largest_value_mem 242/s 421% 12% --
Như bạn có thể thấy, nếu bộ nhớ là không nhiều của một vấn đề, phiên bản với mảng nội bộ là nhanh nhất, theo dõi chặt chẽ bởi các each
iterator, và trong một phần ba xa ... sort
my $highest_val = (keys {$hash{$b} <=> $hash{$a}} keys %hash)[0];
đó trả chìa khóa đó là highe giá trị st. Tôi cho rằng anh ta muốn chìa khóa ánh xạ tới giá trị cao nhất. Nếu không, câu hỏi là quá đơn giản để được hỏi :) (Và trong trường hợp đó, tại sao không chỉ là "đảo ngược phân loại khóa% băm"?) – jrockway
Nó phụ thuộc vào những gì bạn có nghĩa là "giá trị" ở đây. Thông thường một băm được coi là cặp khóa/giá trị, vì vậy tôi sẽ giả định điều tương tự như jrockway. Nhưng nó cũng có thể có nghĩa là những gì amphetamachine nói. Người hỏi nên làm rõ. –
@jrockway - 'Và trong trường hợp đó, tại sao không chỉ là" đảo ngược các phím sắp xếp% băm "? - Bởi vì đó là một loại từ vựng, và' sắp xếp {$ b <=> $ a} 'đánh hai con chim với một hòn đá ở chỗ cả hai một loại số và nó được đảo ngược. – amphetamachine
Các phím được sắp xếp theo giá trị, từ thấp nhất đến cao nhất:
sort { $hash{$a} <=> $hash{$b} } keys %hash
Các phím được sắp xếp theo giá trị, từ cao nhất đến thấp nhất:
reverse sort { $hash{$a} <=> $hash{$b} } keys %hash
Và phần tử đầu tiên
(reverse sort { $hash{$a} <=> $hash{$b} } keys %hash)[0]
Thay thế tàu vũ trụ bằng cmp
để nếm thử.
Tại sao không chỉ sử dụng 'giá trị' thay vì' khóa'? –
Vì anh ta muốn chìa khóa, không phải là giá trị. Giá trị là những gì để sắp xếp theo, chìa khóa là những gì để trở về. Trừ khi tôi đang hiểu sai câu hỏi. – jrockway
Ah, OK, xin lỗi, tôi đã bỏ lỡ điều đó. –
my $highest_val = (sort { $hash{$a} <=> $hash{$b} } keys %hash)[0];
có thể là những gì bạn muốn.
Nếu bạn có một hash rất lớn, bạn có thể muốn sử dụng một cái gì đó giống như một Schwartzian transform:
my @array = map {[$hash{$_},$_]} keys %hash;
my $key_with_highest_value = (sort { $a->[0] <=> $b->[0] } @array)[0]->[1]
Đây là cách nhập nhiều hơn, nhưng là O (n) thay vì O (n log n), thường là một điều tốt. Nếu danh sách của bạn lớn. – jrockway
Biến đổi Schwartzian ở đây chỉ phục vụ để giảm số lần tra cứu bảng băm, và không ** thay đổi độ phức tạp của tìm kiếm - nó vẫn là O (n log n). Cách tiếp cận lặp đi lặp lại từ @jkasnicki là cấp trên. – Alnitak
Sau đây là nhiều không gian hiệu quả và sẽ chạy trong thời gian O (n) thay vì O (n log n) so với các câu trả lời khác sắp xếp băm. Nó giả định giá trị là số nguyên lớn hơn 0 và hàm băm không trống, nhưng nên dễ dàng mở rộng cho trường hợp của bạn.
my $key_for_max_value;
my $max_value = -1;
while ((my $key, my $value) = each %hash) {
if ($value > $max_value) {
$max_value = $value;
$max_key = $key;
}
}
$ key_for_max_value giờ sẽ là khóa tương ứng với giá trị cao nhất.
Có một giả định trong mã của bạn rằng các giá trị của hàm băm không phải là tất cả các số âm nhỏ hơn -1. Bạn chỉ nên làm cho $ max_value giá trị của điều đầu tiên nhìn thấy hoặc một cái gì đó. –
Rất vui được biết _someone_ hiện vẫn đánh giá cao hiệu quả so với tính năng bàn tay ngắn. Giải thích tốt, quá. – amphetamachine
@Kinopiko: Và điều đó có thể được thực hiện với một cái gì đó như 'my $ max_value = undef;' và sau đó, thay đổi 'if' thành' if (! Defined $ max_value || $ value> $ max_value) '. –
my ($max_key, $max_val) = each %hash or die "hash is empty";
while (my ($key, $val) = each %hash) {
$max_key = $key, $max_val = $val if $val > $max_val;
}
Không chắc lý do tại sao tất cả mọi người đang làm điều này bằng tay ...
use List::Util qw(reduce);
my $max_val_key = reduce { $hash{$a} > $hash{$b} ? $a : $b } keys %hash;
- 1. Cách tốt để lấy chìa khóa của giá trị cao nhất của một từ điển trong C#
- 2. Cách an toàn nhất để lặp qua các khóa của mã băm Perl là gì?
- 3. Cách dễ nhất để sắp xếp bản đồ theo giá trị trong Java là gì?
- 4. PHP Lấy giá trị cao nhất từ mảng
- 5. Cách dễ nhất để làm 'là' trong Java là gì?
- 6. Cách tốt nhất để sao chép sâu một băm băm trong Perl là gì?
- 7. làm thế nào để xóa một khóa từ một từ điển có giá trị cao nhất?
- 8. Lấy 3 giá trị cao nhất trong danh sách mảng?
- 9. Cách dễ nhất để lấy tiêu đề từ tệp CSV trong Ruby là gì?
- 10. Trong Perl, làm cách nào để tạo một băm có khóa đến từ một mảng nhất định?
- 11. Tìm giá trị thấp nhất trong băm
- 12. Cách dễ nhất để lật giá trị boolean?
- 13. Sắp xếp mảng các đối tượng bằng cách chìa khóa duy nhất với giá trị ngày
- 14. Trong Ruby, cách sạch nhất để lấy chỉ số của giá trị lớn nhất trong một mảng là gì?
- 15. Cách tốt nhất để băm url trong ruby là gì?
- 16. Cách tốt nhất để lấy các giá trị khác biệt/duy nhất bằng cách sử dụng SPQuery là gì?
- 17. PHP: lấy một khóa duy nhất từ đối tượng
- 18. Lấy giá trị lớn nhất từ đối tượng Json với Javascript
- 19. cách lấy khóa từ giá trị tương ứng trong NSDictionary?
- 20. Cách tốt nhất để lấy giá trị tối thiểu và tối đa từ danh sách Các giá trị so sánh có chứa giá trị null là gì?
- 21. Cách nhanh nhất để lấy giá trị trung bình của một tập hợp các số từ dòng lệnh là gì?
- 22. Cách tốt nhất để tổng hợp các giá trị boolean của từ điển Python là gì?
- 23. Cách dễ nhất để cài đặt một mô-đun Perl bị thiếu là gì?
- 24. Tìm giá trị cao nhất-n trong Bản đồ
- 25. Làm thế nào để lấy chìa khóa từ một TDictionary?
- 26. Tính nhất quán khóa-giá trị trong từ điển python
- 27. Cách dễ nhất trong Perl tinh khiết để truyền từ một tài nguyên HTTP khác là gì?
- 28. Cách lấy tên cột của biến có 10 giá trị cao nhất hàng đầu?
- 29. Cách hiệu quả nhất để tạo cá thể BigInteger từ giá trị int là gì?
- 30. Cách tìm khóa băm có chứa giá trị phù hợp
+1 câu trả lời tuyệt vời và toàn diện! – Alnitak
Câu trả lời kỹ lưỡng. Một bình luận mặc dù: sự phức tạp phân bổ của một tra cứu hash là O (1), không O (log n). – jkasnicki
so sánh tốc độ thế giới thực của tra cứu băm để tra cứu mảng vẫn hiển thị mối quan hệ phi tuyến. với 10 phần tử, một mảng là% 50 nhanh hơn một băm, với 10000 phần tử, nó nhanh hơn 100%, với 1.000.000 phần tử nhanh hơn 210% ... –