Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I felt bad for only <em>hinting</em> on backtracking and recursion in a comment. Here's an explanation:</p> <h3>Strategy:</h3> <p>Focus on the tokens <em>between</em> wilcards (the wildcards are not what should be matched).</p> <ul> <li>extract first token from pattern</li> <li>exit with success for no (more) tokens</li> <li>for each token match in input <ul> <li>match the remainder of the pattern against the remainder of the input</li> <li>if no successful submatch, fail, otherwise done</li> </ul></li> </ul> <p>There is recursion (the matching of the remainder class match(....) recursively).</p> <p>There is backtracking (if the recursive match doesn't succeed, we try the next token submatch)</p> <h3>Sample (<em>see <a href="https://ideone.com/yApYp" rel="nofollow">https://ideone.com/yApYp</a></em>)</h3> <p>Only using loops and <code>std::string</code> interface (well, and <code>iostreams</code> for displaying test output) :)</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; typedef std::string::const_iterator It; /* * Extract sequences of non-wildcard characters from pattern range */ std::string extract_token(It &amp;s, It e) // [s,e) is (sub)pattern { It wcard; for (wcard=s; wcard!=e; ++wcard) if ('?' == *wcard) break; std::string token(s,wcard); for (s=wcard; s!=e; ++s) if ('?' != *s) break; // treat '??' as '?' in pattern return token; } /* * Match a (sub)pattern against a (sub)input * * (See "Strategy" above) */ bool match(It patb, It pate, const std::string&amp; input) { while (patb != pate) { // get next token from pattern, advancing patb std::string token = extract_token(patb, pate); // updates patb if (!token.empty()) // could happen if pattern begins/ends with redundant '?' { size_t submatch = input.find(token); // first submatch please while (std::string::npos != submatch) // while we have a submatch { if (match(patb, pate, input.substr(token.size()))) return true; // match completed successfully // look for later potential submatches (*backtrack*) submatch = input.find(token, submatch+1); } return false; // required token not found } } return true; // no (remaining) pattern, always match } bool match(const std::string&amp; pattern, const std::string&amp; input) { // just relay to overload more suited for recursion return match(pattern.begin(), pattern.end(), input); } ////////////////////// // TEST PROGRAM void test(const std::string&amp; pattern, const std::string&amp; input) { std::cout &lt;&lt; std::boolalpha; std::cout &lt;&lt; "match(\"" &lt;&lt; pattern &lt;&lt; "\", \"" &lt;&lt; input &lt;&lt; "\") =&gt; " &lt;&lt; match(pattern, input) &lt;&lt; std::endl; } int main() { // matches test("?????", ""); test("?????", "?????"); test("", ""); test("", "glorious"); test("?r?o", "glorious"); test("some?words?exist", "some silly words should, most definitely, be existing"); test("some??words?exist?", "some silly words should, most definitely, be existing"); // failing matches test("_", ""); test("_", "glorious"); test("_", "glorious"); test("glorious", "glo?ious"); test("?some??words?exist?", "bogus"); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload