Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Количество одинаковых элементов массива


Автор: Гость_Игорь 3.10.2005, 10:18
Здравствуйте,
никак не могу разобраться с этой задачей:

необходимо посчитать количество одинаковых элементов в массиве.
те есть массив, например:
@dot=qw(1 2 3 6 7 2 1 1 2 6 1);

необходимо вывести такую статистику:
единиц - 4 штуки,
двоек - 3 штуки и тп

при этом надо учесть, что сам массив произвольного размера и количество повторяющихся элементов неизвестно.

Единственно что пришло в голову - скопировать массив и сравнивать каждый элемент массива со всеми элементами его копии. Но этот вариант крайне ресурсоёмкий. Наверняка есть какое-то более простое решение.

Специалисты, помогите пожалуйста.
Спасибо большое заранее.



Автор: Bolt 3.10.2005, 10:22
это делается с помощью хэша

Автор: korob2001 3.10.2005, 11:13
Код

#!/usr/bin/perl -w
use strict;
my @dot=qw(1 2 3 6 7 2 1 1 2 6 1);
my %res = ();
grep { $res{ $_ }++ } (@dot);
foreach ( sort { $a <=> $b } keys %res )
{
          print "$_ - $res{ $_ } øòóê.\n";
}

Проходим по всему массиву, каждый элемент устанавливаем как ключь хеша, а значение инкрементируем. Так как хеш не может содержать одинаковые ключи, то если данный ключь был установлен ранее, значит просто инкрементируем его значение. В итоге получаем хеш, где все уникальные елементы - это ключи, а их значения - кол-во этих элементов в массиве. Кстати, этого же результата можно добиться и не используя grep, а с помощью любого цикла. Вот тот же пример, только с использованием цикла while:
Код

#!/usr/bin/perl -w
use strict;
my @dot=qw(1 2 3 6 7 2 1 1 2 6 1);
my(%res, $element) = ();

$res{ $element }++ while ( $element = shift @dot );

foreach my $key ( sort { $a <=> $b } keys %res )
{
          print "$key - $res{ $key } øòóê.\n";
}

Здесь стоит учитывать один момент, после окончания цикла while, массив будет пуст. Этот способ хорошо применять в том случае, если массив больше не нужен и он очень большой.

Автор: Sadok 3.10.2005, 11:15
Код
use strict;
my @dot=qw(1 2 3 6 7 2 1 1 2 6 1);
my %seen = ();
my $item;
foreach $item (@dot) {
        $seen{$item}++ ;
      }

После чего в хеше %seen имеем в качестве ключей элементы массива @dot, в качестве значений - их количество

Автор: Guest 4.10.2005, 15:52
Many thanx всем,
всё работает :-)

а вот ещё один вариант подсказали:

my @dot=qw(1 2 3 6 7 2 1 1 2 6 1);
my %hash;
$hash{$_}++ for @dot;
print "$_ => $hash{$_}\n" for sort keys %hash;


2 korob2001:
спасибо за подробное объяснение,
именно они и помогают изучать perl



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)