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


Автор: Suppir 17.10.2010, 17:41
$line = "О перечне объектов культурного наследия"

Как посчитать количество пробелов в строке, не изменяя строку? 


Автор: Suppir 17.10.2010, 18:10
Вопрос снят:

Код

while($line=~ s/(\s)/$1/g){$c++}
print $c;

Автор: Pfailed 17.10.2010, 19:46
Насколько помню в кэмелбуке говорилось, что лучшим вариантом для решения такой задачи является использование tr///
Код

$cnt = $line =~ tr/ / /;


Добавлено через 4 минуты и 54 секунды
Кстати судя по всему когда замена происходит на туже заменяемую букву tr не модифицирует исходную строку. Таким образом можно посчитать количество пробелов даже в анонимной строке.
Код

$cnt =  "О перечне объектов культурного наследия" =~ tr/ / /;


Автор: nagual2 3.3.2011, 03:19
Вариант с while зацикливается  smile 
Вариант с tr непозволяет использовать регулярные ...

Вот так работает  my @cifra = $name =~ m!\d!g; в моем случае нужно посчитать цифры.

Автор: arto 3.3.2011, 08:26
#perl -MBenchmark=timethese -e '$aa = join "",map { rand(10)>2 ? "a" : "1" } 1..$ARGV[1]; timethese ($ARGV[0], { A => sub { return scalar split "(?:\\d)",$aa }, B => sub { my @aa = $aa =~ m#\d+#g; return $#aa }, C => sub { my $n; $n++ while ($aa =~ m#\d#g); return $n } } )' 10000 10240   
Benchmark: timing 10000 iterations of A, B, C...
         A:  4 wallclock secs ( 3.82 usr +  0.06 sys =  3.88 CPU) @ 2577.32/s (n=10000)
         B: 14 wallclock secs (13.04 usr +  0.04 sys = 13.08 CPU) @ 764.53/s (n=10000)
         C:  7 wallclock secs ( 7.79 usr +  0.02 sys =  7.81 CPU) @ 1280.41/s (n=10000)

Автор: nagual2 6.3.2011, 14:02
split hазбивает строку на отдельные строки, используя в качестве разделителя образец, задаваемый регулярным выражением. В случае когда крайний символ удовлетворяет выражению он вернет неверный для нас результат. Скорее как то так sub { return scalar split "(?:\\d)","a".$aa."a" }

Добавлено через 3 минуты и 34 секунды
Исходный тест:
Benchmark: timing 10000 iterations of A, B, C...
         A:  3 wallclock secs ( 3.01 usr +  0.00 sys =  3.01 CPU) @ 3324.68/s (n=10000)
         B: 13 wallclock secs (12.88 usr +  0.00 sys = 12.88 CPU) @ 776.70/s (n=10000)
         C:  7 wallclock secs ( 7.12 usr +  0.00 sys =  7.12 CPU) @ 1405.05/s (n=10000)

Исправленный:
Benchmark: timing 10000 iterations of A, B, C...
         A:  4 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @ 3137.25/s (n=10000)
         B: 13 wallclock secs (13.21 usr +  0.00 sys = 13.21 CPU) @ 756.95/s (n=10000)
         C:  8 wallclock secs ( 7.59 usr +  0.00 sys =  7.59 CPU) @ 1316.87/s (n=10000)

Автор: gcc 6.3.2011, 15:18
если бы задача была не такая легкая, то можно было бы связывать с xor

например,  вариант amg
Код

    $hash->{$1}++
      while $_[0] =~ /(\d+\.\d+\.\d+\.\d+)/smg xor 
         grep { $_ > 255 } split /\./,
        $1;


ускоряет довольно сильно

Автор: nagual2 6.3.2011, 15:25
 split /\./, А если точка будет стоять в начале строки или в конце то результат будет неверный ...

Автор: gcc 6.3.2011, 15:50
результат чего?
попробовать религия запрещает?

Код

perl -MData::Dumper -e ' $hash->{$1}++ while ".193.201.81.81. .193.201.81.81." =~ /(\d+\.\d+\.\d+\.\d+)/smg xor grep { $_ > 255 } split /\./, $1; print Dumper $hash'

Автор: nagual2 6.3.2011, 19:10
Автор темы хотел посчитать пробелы. Мне нужно было посчитать точки. В тесте с ip сам ip выдает верно, но условие задачи немного другое.

Добавлено через 2 минуты и 15 секунд
split считает слева направо, если первый символ строки подходит под условие то в выдаваемом результате в массиве первый элемент будет пустой ...

Автор: KSURi 9.3.2011, 15:17
Код

my $count =()= $text =~ /[ .]/g; # secret goatse operator

Автор: nagual2 9.3.2011, 15:49
perl -MBenchmark=timethese -e '    $aa = join "",map { rand(10)>2 ? "a" : "1" } 1..$ARGV[1];     timethese ($ARGV[0], { A => sub { return scalar split "(?:\\d)","a".$aa."a" }, B => sub
 { my @aa = $aa =~ m#\d+#g; return $#aa }, C => sub { my $n; $n++ while ($aa =~ m#\d#g); return $n }, D => sub { my $n =()= $aa =~ /[ .]/g; return $n }} )' 10000 10240


# ./test.sh
Benchmark: timing 10000 iterations of A, B, C, D...
         A:  4 wallclock secs ( 3.06 usr +  0.00 sys =  3.06 CPU) @ 3265.31/s (n=10000)
         B: 13 wallclock secs (12.87 usr +  0.00 sys = 12.87 CPU) @ 777.17/s (n=10000)
         C:  7 wallclock secs ( 7.12 usr +  0.00 sys =  7.12 CPU) @ 1405.05/s (n=10000)
         D:  0 wallclock secs ( 0.34 usr +  0.00 sys =  0.34 CPU) @ 29767.44/s (n=10000)
            (warning: too few iterations for a reliable count)

Я где то ошибся в тесте ?

perl -MBenchmark=timethese -e '    $aa = join "",map { rand(10)>2 ? "a" : "1" } 1..$ARGV[1];     timethese ($ARGV[0], { A => sub { return scalar split "(?:\\d)","a".$aa."a" }, B => sub
 { my @aa = $aa =~ m#\d+#g; return $#aa }, C => sub { my $n; $n++ while ($aa =~ m#\d#g); return $n }, D => sub { my $n =()= $aa =~ /\./g; return $n }} )' 10000 10240

# ./test.sh
Benchmark: timing 10000 iterations of A, B, C, D...
         A:  4 wallclock secs ( 3.13 usr +  0.00 sys =  3.13 CPU) @ 3192.02/s (n=10000)
         B: 13 wallclock secs (12.98 usr +  0.00 sys = 12.98 CPU) @ 770.62/s (n=10000)
         C:  8 wallclock secs ( 7.95 usr +  0.00 sys =  7.95 CPU) @ 1257.37/s (n=10000)
         D:  0 wallclock secs ( 0.08 usr +  0.00 sys =  0.08 CPU) @ 128000.00/s (n=10000)
            (warning: too few iterations for a reliable count)

Автор: arto 9.3.2011, 17:03
да. в варианте D вы ищете что-то непонятное.
остальные ищут числа.

Автор: nagual2 9.3.2011, 18:04
perl -MBenchmark=timethese -e '    $aa = join "",map { rand(10)>2 ? "a" : "1" } 1..$ARGV[1];     timethese ($ARGV[0], { A => sub { return scalar split "(?:\\d)","a".$aa."a" }, B => sub
 { my @aa = $aa =~ m#\d+#g; return $#aa }, C => sub { my $n; $n++ while ($aa =~ m#\d#g); return $n }, D => sub { my $n =()= $aa =~ /\d/g; return $n }} )' 10000 10240

./test.sh
Benchmark: timing 10000 iterations of A, B, C, D...
         A:  3 wallclock secs ( 3.24 usr +  0.00 sys =  3.24 CPU) @ 3084.34/s (n=10000)
         B: 13 wallclock secs (13.42 usr +  0.00 sys = 13.42 CPU) @ 745.05/s (n=10000)
         C:  9 wallclock secs ( 8.27 usr +  0.00 sys =  8.27 CPU) @ 1208.69/s (n=10000)
         D: 12 wallclock secs (12.09 usr +  0.00 sys = 12.09 CPU) @ 826.87/s (n=10000)

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