Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If possible, I'd suggest breaking the logic up into slightly smaller units, and pushing more of the logic into the classes -- right now, <code>main</code> does quite a lot more than I'd like to see there, and (particularly) knows more about the internals of the classes than I'd like to see either.</p> <p>If I were doing it, I'd start with a map that knew how to filter out words, so it can only accept what it's supposed to:</p> <pre><code>class Map { std::map&lt;std::string, int&gt; counts; public: struct Filter { virtual bool operator()(std::string const &amp;) const = 0; }; Map(Filter const &amp;f) : filter(f) {} bool InsertWord(std::string const &amp;word) { return filter(word) &amp;&amp; (++counts[word] != 0); } friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, Map const &amp;m) { std::copy(m.counts.begin(), m.counts.end(), std::ostream_iterator&lt;count&gt;(std::cout, "\n")); return os; } private: Filter const &amp;filter; }; </code></pre> <p>Then we'd need some derivatives of Filter to do the real filtering. These probably don't work the way you really want; they're really just placeholders:</p> <pre><code>struct Num : Map::Filter { bool operator()(std::string const &amp;w) const { return isdigit(w[0]) != 0; } }; struct Punct : Map::Filter { bool operator()(std::string const &amp;w) const { return ispunct(w[0]) != 0; } }; struct Letter : Map::Filter { bool operator()(std::string const &amp;w) const { return isalpha(w[0]) != 0; } }; </code></pre> <p>Then MapWorks can delegate almost all the real work to the Map (which in turn uses a Filter):</p> <pre><code>class MapWorks { Map num; Map punct; Map letter; public: // For the moment, these allocations just leak. // As long as we only create one MapWorks object, // they're probably not worth fixing. MapWorks() : num(Map(*new Num())), punct(Map(*new Punct())), letter(Map(*new Letter())) {} // Try adding the word until we find a Map // that accepts it. bool push_back(std::string const &amp;word) { return num.InsertWord(word) || punct.InsertWord(word) || letter.InsertWord(word); } // Write out by writing out the individual Map's: friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, MapWorks const &amp;m) { return os &lt;&lt; m.num &lt;&lt; "\n" &lt;&lt; m.punct &lt;&lt; "\n" &lt;&lt; m.letter &lt;&lt; "\n"; } }; </code></pre> <p>With these in place, <code>main</code> becomes pretty simple: (though for the moment, I've just had it read a whole file instead of looking for "BEGIN" and "FINIS"):</p> <pre><code>int main() { MapWorks m; std::string temp; while (std::cin &gt;&gt; temp) m.push_back(temp); std::cout &lt;&lt; m; return 0; } </code></pre> <p>There are a few other bits and pieces, such as typedef'ing the count type and defining an inserter for it, but they're pretty minor details.</p>
 

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