Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If i had to do this in the confines of your proposed usage (maintain a key-map for quick counter updates, then dump a sorted result), I would likely use an unordered map and a pointer vector. With this I'm assuming the primary reason you want some indexed-key soluton in the first place is to make data processing significantly quicker when updating counts.</p> <p>In other words, you're looking to get a good speed-bump out of code that does this:</p> <pre><code>++product[ id ]; // increment counter for product 'id' in our keyed-container. </code></pre> <p>But still be able to report output sorted not on id, but rather on the accumulated count of each id. That being said, the following, though a little dense, will do <em>exactly</em> that:</p> <pre><code>#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;algorithm&gt; #include &lt;vector&gt; #include &lt;ctime&gt; #include &lt;unordered_map&gt; #include &lt;iterator&gt; #include &lt;iomanip&gt; using namespace std; int main(int argc, char *argv[]) { typedef std::unordered_map&lt;int, int&gt; Products; Products product; // fill with random data for our test. std::srand((unsigned)time(0)); for (int i=1;i&lt;20;++i) { product[i] = rand() % 50 + 1; cout &lt;&lt; setw(3) &lt;&lt; i &lt;&lt; " ==&gt; " &lt;&lt; product[i] &lt;&lt; endl; } cout &lt;&lt; endl; // now setup a one-shot sort. we're using a vector of // pointers to our map value type std::vector&lt;const Products::value_type*&gt; data; data.reserve(product.size()); std::transform(product.begin(), product.end(), std::back_inserter(data), [](const Products::value_type&amp; obj) { return std::addressof(obj); }); // sort the vector by value (second) std::stable_sort(data.begin(), data.end(), [](const Products::value_type* left, const Products::value_type* right) { return left-&gt;second &lt; right-&gt;second; }); // results are in the vector as pointers. the original map is unchanged. for (auto ptr : data) cout &lt;&lt; setw(3) &lt;&lt; ptr-&gt;first &lt;&lt; " ==&gt; " &lt;&lt; ptr-&gt;second &lt;&lt; endl; return EXIT_SUCCESS; }; </code></pre> <p><strong>Sample Run</strong></p> <pre><code> 1 ==&gt; 42 2 ==&gt; 18 3 ==&gt; 35 4 ==&gt; 1 5 ==&gt; 20 6 ==&gt; 25 7 ==&gt; 29 8 ==&gt; 9 9 ==&gt; 13 10 ==&gt; 15 11 ==&gt; 6 12 ==&gt; 46 13 ==&gt; 32 14 ==&gt; 28 15 ==&gt; 12 16 ==&gt; 42 17 ==&gt; 46 18 ==&gt; 43 19 ==&gt; 28 20 ==&gt; 37 4 ==&gt; 1 11 ==&gt; 6 8 ==&gt; 9 15 ==&gt; 12 9 ==&gt; 13 10 ==&gt; 15 2 ==&gt; 18 5 ==&gt; 20 6 ==&gt; 25 14 ==&gt; 28 19 ==&gt; 28 7 ==&gt; 29 13 ==&gt; 32 3 ==&gt; 35 20 ==&gt; 37 1 ==&gt; 42 16 ==&gt; 42 18 ==&gt; 43 12 ==&gt; 46 17 ==&gt; 46 </code></pre> <p>I've used this method in the past because it is swimmingly-efficient for more complex structures that are expensive to copy into temporary containers for sorting. That the ending pointer-vector references the <em>real</em> data in the map is a nicety that, while probably overkill for this specific problem, certainly has reaps of benefits as a general solution.</p> <p>That being said, if all you want is an int-to-int dump, sorted on second-int rather than your map key, this will likewise do the trick, though it does replicate data out of your container to accomplish the end-goal:</p> <pre><code>#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;algorithm&gt; #include &lt;vector&gt; #include &lt;ctime&gt; #include &lt;unordered_map&gt; #include &lt;iterator&gt; #include &lt;iomanip&gt; using namespace std; int main(int argc, char *argv[]) { typedef std::unordered_map&lt;int, int&gt; Products; Products product; // fill with random data for our test. std::srand((unsigned)time(0)); for (int i=1;i&lt;20;++i) { product[i] = rand() % 50 + 1; cout &lt;&lt; setw(3) &lt;&lt; i &lt;&lt; " ==&gt; " &lt;&lt; product[i] &lt;&lt; endl; } cout &lt;&lt; endl; // copy the values from the map to a sort bed. std::vector&lt;std::pair&lt;int,int&gt;&gt; vals; std::copy(product.begin(), product.end(), back_inserter(vals)); std::stable_sort(vals.begin(), vals.end(), [](const std::pair&lt;int,int&gt;&amp; left, const std::pair&lt;int,int&gt;&amp; right) { return left.second &lt; right.second; }); // dump to stdout for (auto val : vals) cout &lt;&lt; setw(3) &lt;&lt; val.first &lt;&lt; " ==&gt; " &lt;&lt; val.second &lt;&lt; endl; return EXIT_SUCCESS; } </code></pre> <p><strong>Sample Output</strong></p> <pre><code> 1 ==&gt; 48 2 ==&gt; 30 3 ==&gt; 25 4 ==&gt; 32 5 ==&gt; 34 6 ==&gt; 21 7 ==&gt; 26 8 ==&gt; 6 9 ==&gt; 50 10 ==&gt; 28 11 ==&gt; 50 12 ==&gt; 32 13 ==&gt; 35 14 ==&gt; 17 15 ==&gt; 33 16 ==&gt; 30 17 ==&gt; 13 18 ==&gt; 1 19 ==&gt; 50 18 ==&gt; 1 8 ==&gt; 6 17 ==&gt; 13 14 ==&gt; 17 6 ==&gt; 21 3 ==&gt; 25 7 ==&gt; 26 10 ==&gt; 28 2 ==&gt; 30 16 ==&gt; 30 4 ==&gt; 32 12 ==&gt; 32 15 ==&gt; 33 5 ==&gt; 34 13 ==&gt; 35 1 ==&gt; 48 9 ==&gt; 50 11 ==&gt; 50 19 ==&gt; 50 </code></pre>
    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. VO
      singulars
      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