I'd probably simplify that a bit, with a possible (minor) speed benefit.

First, we should conceptualise how to approach the problem. As a human. (My experience with Perl is that it's even better than many other languages at doing what a human does, which improves both readability and reliability.) So, what I would do, as a human, would be to look for each letter in the target string, and if all of them are there, then I have a match. That "all" is a big clue - checking modules for such behaviour, I find it in List::MoreUtils. (Side note: since other monks have pointed me to List::MoreUtils, I've found more and more use for it, so much so that I'm now wishing it were core!)

The advantage, of course, of using such a tool is that it short-circuits your code (returning at the first failure rather than continuing), and, in this case, it's written in XS, so should be faster than a simple perl duplicate. In the worst case, where all letters are present (or all but the last letter), this should perform basically as well as yours (except I don't need to create a list to count it), and on average, it should perform better. However, that should all be pretty minimal - instead, the real benefit is doing what a human does exactly the same way. And that makes it more likely to work in weird circumstances.

So, after all that build-up, I had better show some code. Note that I've renamed the function because I like my boolean-returning functions to sound, well, boolean. "Check for letters" doesn't tell me what it returns (sounds like it doesn't have a return value, actually)...

#! /usr/bin/perl use strict; use warnings; use List::MoreUtils qw(all); sub hasAllLetters { my ($sentence, $letters) = @_; # all we're doing is checking for each letter. all { $sentence =~ $_ } split //, $letters; # same as above, but with index which I think is less readable. #all { index($sentence, $_) >= $[ } split //, $letters; } # tests for my $t ( [ "abxcd zwe rrv", "zxv" ], [ "abxcd zwe rrv", "qxv" ], ) { if (hasAllLetters(@$t)) { print "YES [$t->[0]] ~~ [$t->[1]]\n"; } else { print "NO [$t->[0]] !~ [$t->[1]]\n"; } }
(If performance was really an issue, I'd not only benchmark it, but I'd use @_ directly instead of giving them readable names.)


In reply to Re^2: check if all certain chars are found in a sentence by Tanktalus
in thread check if all certain chars are found in a sentence by tallulah

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.