Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are two aspects to this question: parsing &amp; sorting.</p> <ul> <li>You can use <em>regular expressions</em> to check the user-input data-types.</li> <li>You can use <code>cin</code> to parse the data.</li> </ul> <p><strong>First:</strong> realise that you cannot <em>necessarily</em> know the <em>type</em> of your users input until you have received all of it ~eg: consider a list of user names :</p> <pre><code>728278243 390349346 495045594 elizabeth </code></pre> <p>Hence, best not to assume to know best about the incoming data (<em>can lead to a frustrating user-experience</em>) but instead, prefer to treat everything as potentially a string. Store all raw input as strings so you can output in same format as input. you can use say, an enumerated type to switch inside a sort comparator <em>or</em> consider using a <code>mutliset/multimap</code>. here you will be building an <em>ordered</em> set. so there is no need to sort. NB: the complexity for constructing an ordered set of N elements <em>or</em>, for a single sort on N unsorted list elements, is roughly equivalent ~> NlogN</p> <p>For your task-in-hand, it hardly matters but in reality depending upon upon how the list is used, one or other approach will be far more appropriate in performance terms.</p> <p>If you have already used the likes of <code>std::vector</code> then <code>std::multimap</code> shouldn't be too scary. Loosely, it is an associated array of key-value pairs. the <em>multi</em> here meaning it can store multiple elements with the <em>same</em> key (which here, you want). </p> <p><br/>In this example i am using the <em>boost</em> regex library in order to determine some <em>funky</em> input data-types. <br/>(eg: <code>sudo apt-get install libboost-regex1.46-dev</code>)</p> <p>This <em>regex</em> might seem arcane but there are many examples on the i/web for practically every conceivable pattern. [<em>NB: C++11 regex is pretty-much a drop-in replacement for boost regex. ie: boost regex should be forward-compatible with the emerging C++11 standard</em>]</p> <p><br/><strong>blah.cpp:</strong></p> <pre><code>#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;list&gt; #include &lt;map&gt; #include &lt;set&gt; #include &lt;boost/regex.hpp&gt; //NB: GNU gcc added *experimental support for regular expressions in TR1 v 4.3.0. // compile with: -std=c++0x using namespace std; using namespace boost; //some example input data-types (perhaps notably missing a date!) const regex re_char("[^0-9]", regex_constants::extended); //non numeric chars const regex re_digit("[[:digit:]]+", regex_constants::extended); //a string of only digits in range [0..9] ~ie: Z+ const regex re_xdigit("0[xX][[:xdigit:]]+", regex_constants::extended); //support hex iff starts with '0x' or '0X' const regex re_float("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?", regex_constants::extended); //all kinds of numbers int main(int argc, char** argv) { int i, countc=0; double d; string str; int element_count; do { cout &lt;&lt; "how many elements will there be? "; if (cin &gt;&gt; element_count) break; cin.clear(); cin &gt;&gt; str; cout &lt;&lt; "\033[A\033[2K" &lt;&lt; flush; } while(13); cin.ignore(128,'\n'); multimap&lt;double, string&gt; list_num; multimap&lt;double, string&gt; list_fp; //NB: below, by way of example, construction using the 'greater&lt;int&gt;' comparison class achieves _descending_ order multimap&lt;int, string, greater&lt;int&gt; &gt; list_int; list&lt;string&gt; list_str; for (int next=0; next &lt; element_count; next++) { cout &lt;&lt; "\033[A\033[2K" &lt;&lt; flush; cout &lt;&lt; "enter next element in list ["&lt;&lt; next+1 &lt;&lt; "/" &lt;&lt; element_count &lt;&lt; "] : "; getline (cin,str); if (regex_match(str, re_xdigit)) { //see all about manipulators here: //http://www.cplusplus.com/reference/iostream/istream/operator%3E%3E/ stringstream(str) &gt;&gt; hex &gt;&gt; i; list_int.insert(pair&lt;int, string&gt;(i, str)); list_num.insert(pair&lt;double, string&gt;(i, str)); } else if (regex_match(str, re_digit)) { stringstream(str) &gt;&gt; i; list_int.insert(pair&lt;int, string&gt;(i, str)); list_num.insert(pair&lt;double, string&gt;(i, str)); } else if (regex_match(str, re_float)) { stringstream(str) &gt;&gt; d; list_fp.insert(pair&lt;double, string&gt;(d, str)); list_num.insert(pair&lt;double, string&gt;(d, str)); } if (regex_match(str, re_char)) countc++; list_str.push_back(str); } cout &lt;&lt; "\033[A\033[2K" &lt;&lt; flush; cout &lt;&lt; "input: unsorted list:" &lt;&lt; endl; for (list&lt;string&gt;::iterator it=list_str.begin(); it!=list_str.end(); it++) cout &lt;&lt; *it &lt;&lt; endl; if (list_int.size() == element_count) { cout &lt;&lt; endl &lt;&lt; "output: sorted list of Z+ types:" &lt;&lt; endl; for (multimap&lt;int, string&gt;::iterator it=list_int.begin() ; it != list_int.end(); it++ ) cout &lt;&lt; (*it).second &lt;&lt; endl; } else if (list_fp.size() == element_count) { cout &lt;&lt; endl &lt;&lt; "output: sorted list of fp types:" &lt;&lt; endl; for (multimap&lt;double, string&gt;::iterator it=list_fp.begin() ; it != list_fp.end(); it++ ) cout &lt;&lt; (*it).second &lt;&lt; endl; } else if (list_num.size() == element_count) { cout &lt;&lt; endl &lt;&lt; "output: sorted list of numeric types:" &lt;&lt; endl; for (multimap&lt;double, string&gt;::iterator it=list_num.begin() ; it != list_num.end(); it++ ) cout &lt;&lt; (*it).second &lt;&lt; endl; } else //output as sorted strings ~but in _descending_ order, using reverse iterator, by way of example { list_str.sort(); //but best to use list_str.sort(greater&lt;string&gt;()); with forward iterators cout &lt;&lt; endl &lt;&lt; "output: sorted list of " &lt;&lt; (countc == element_count ? "non numeric char" : "string") &lt;&lt; " types:" &lt;&lt; endl; for (list&lt;string&gt;::reverse_iterator it=list_str.rbegin(); it!=list_str.rend(); ++it) cout &lt;&lt; *it &lt;&lt; endl; } return 0; } </code></pre> <p>Example was compiled &amp; run on Ubuntu. Commandline stuff:</p> <pre><code>$ $ lsb_release -d Description: Ubuntu 11.10 $ g++ --version g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 $ g++ --pedantic -oblah blah.cpp -lboost_regex $ ./blah input: unsorted list: 4.77 2.0e+2 -.3 11 0x10 output: sorted list of numeric types: -.3 4.77 11 0x10 2.0e+2 $ </code></pre> <p><br/><strong>NB:</strong> This is example code:</p> <ul> <li>There are many optimisations that can be made here. You clearly don't <em>need</em> so many <code>stl</code> containers as i am using.</li> <li>I do not strictly deal with the direction of the sort (but show a couple of ways it may be achieved).</li> <li>It might also be nice to encapsulate the type-specific functionality in C++ objects; have a base class &amp; then derived classes for each <em>type</em> you wish to support ~but this <em>homework</em> right? -so probably not worth going over-board then ;)</li> </ul>
    singulars
    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. This table or related slice is empty.
    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