Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: Общие вопросы > Посчитать количество вхождения символа с строку |
Автор: Suppir 17.10.2010, 17:41 |
$line = "О перечне объектов культурного наследия" Как посчитать количество пробелов в строке, не изменяя строку? |
Автор: Suppir 17.10.2010, 18:10 | ||
Вопрос снят:
|
Автор: Pfailed 17.10.2010, 19:46 | ||||
Насколько помню в кэмелбуке говорилось, что лучшим вариантом для решения такой задачи является использование tr///
Добавлено через 4 минуты и 54 секунды Кстати судя по всему когда замена происходит на туже заменяемую букву tr не модифицирует исходную строку. Таким образом можно посчитать количество пробелов даже в анонимной строке.
|
Автор: nagual2 3.3.2011, 03:19 |
Вариант с while зацикливается ![]() Вариант с 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
ускоряет довольно сильно |
Автор: nagual2 6.3.2011, 15:25 |
split /\./, А если точка будет стоять в начале строки или в конце то результат будет неверный ... |
Автор: gcc 6.3.2011, 15:50 | ||
результат чего? попробовать религия запрещает?
|
Автор: nagual2 6.3.2011, 19:10 |
Автор темы хотел посчитать пробелы. Мне нужно было посчитать точки. В тесте с ip сам ip выдает верно, но условие задачи немного другое. Добавлено через 2 минуты и 15 секунд split считает слева направо, если первый символ строки подходит под условие то в выдаваемом результате в массиве первый элемент будет пустой ... |
Автор: KSURi 9.3.2011, 15:17 | ||
|
Автор: 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) |