Finding the number of times a query string appears in a vector of strings c++ I wrote some code that iterates over some queries and counts the number of times each query appears in a vector of words. My first iteration iterated through all the words in the vector for each query which is wasteful. I improved it and come up with this. 

unordered_map&lt;string, int&gt; matchingStrings(vector&lt;string&gt;&amp; strings, vector&lt;string&gt;&amp; queries) {
    sort(strings.begin(), strings.end());
    sort(queries.begin(), queries.end());
    unordered_map&lt;string,int&gt; counts;
    auto s = strings.begin();
    bool notfound;
    int count = 0;
    for (auto&amp; q : queries) {
        count = 0;
        auto temp = s;
        notfound = false;
        while (q.compare(*s)) {
            if (s != strings.end()-1) {
                s++;
            }
            else {
                counts[q] = count;
                notfound = true;
                s = temp;
                break;
            }
        }
        if (notfound) continue;
        while (!q.compare(*s)) {
            count++;
            if (s != strings.end()-1) {
                s++;
            }
            else {
                break;
            }
        }
        counts[q] = count;
    }
    return counts;
}


It works on my test cases, so I think it has some place here on code review. I would like to know how I can tidy this up? also! In the case where the query is not found we go back to the string the non-present query started at. Is there a way to get around this?

By "tidy this up" I mean, avoiding code repetition and maybe some alternative ideas? Possibly some modern c++ tools even?
You start by sorting both the queries and the strings to search, but you don't seem to make a whole lot of use of the fact that afterwards they're sorted. Fortunately, parts of the standard library make it fairly easy to take better advantage of that as well.
It looks like you've preceded your code by something like using namespace std;. This is generally considered a poor idea, and should usually be avoided.
When you just want to know if one string equals another, it's often simpler and more readable to use something like if (a == b) than if (!a.compare(b)).
The single biggest thing I see here is that the standard library already provides most of the functionality you want, so using it can make the code quite a bit simpler.


I'd probably write the code something on this general order:

[edit: modified code to optimize for unique queries, as OP stated in comment.]

std::unordered_map&lt;std::string, int&gt; matchingStrings(std::vector&lt;std::string&gt; &amp;strings, 
                                                     std::vector&lt;std::string&gt; &amp;queries) 
{
    std::sort(strings.begin(), strings.end());
    std::sort(queries.begin(), queries.end());

    std::unordered_map&lt;std::string, int&gt; counts;

    auto start = strings.begin();

    for (auto const &amp;q : queries) {
        auto p = std::equal_range(start, strings.end(), q);
        counts[q] = p.second - p.first;
        start = p.second;
    }
    return counts;
}


std::equal_range looks for a range (in a sorted sequence) of objects that are equal to one that's specified. It can use a binary search to find the beginning and end of the range, so if the number of strings being searched is large, it can potentially save quite a bit of time. It returns an std::pair--the first item is an iterator to the beginning of the range, and the second an iterator to the beginning of the range. So, we use that to find all the strings that match a given query, and count them by subtracting the two.