Pointless typedef
In C, it's fairly common to have a typedef
like this:
typedef struct tag {
// ...
} type_name;
This allows you define a variable with just type_name var_name;
. A struct
definition like this:
struct tag {
// ...
};
...requires that to define a variable of this type, you need to type struct tag var_name;
. In C++, that's unnecessary though. Using just:
struct type_name {
// ...
};
... lets you define a variable as type_name var_name;
already. In this case, you've left the final type_name
off, so your typedef
isn't syntactically correct. It's probably open to some question whether your code should compile at all (but either way, it's incorrect).
Container choice
A great deal here depends on the actual data. If the data you've shown is truly representative (there really are only a couple of bad IDs) your current choice of containers is probably quite good.
On the other hand, if this is a reduced sample, and in real use you might have dozens or even hundreds of IDs in your black list, then it's probably worth considering using something like an std::unordered_set
.
Algorithm choice
Another obvious possibility (if the number of bad IDs might get large) would be to use a binary search instead of a linear search through the bad IDs. Note that you've shown in the bad IDs in sorted order--if you were to use a binary search, you'd be taking advantage of this, and their being sorted would be required, which it currently isn't.
Item grouping
Unless you're truly required to show the message about an item being good/bad in the order in which they originally appeared, I'd strongly prefer to see output something like this:
Good items:
A
B
D
Bad items:
C
E
Avoid std::endl
I'd use '\n'
instead of std::endl
. Using std::endl
not only prints a new-line to the stream, but also flushes the stream. This is rarely desirable or useful, and if you're producing a substantial amount of output, it'll typically cause a substantial slow-down.
Don't repeat yourself
I'd rather have a single function that does the formatting and display of the output, something on this order:
template <class It>
void show(std::string const &caption, It beg, It end) {
std::cout << caption << ":\n";
for (; beg != end; ++beg)
std::cout << beg->id << "\n";
}
Format data
Instead of putting all the contents of your vector
on one long line, consider formatting it with (for example) one item per line:
std::vector<mystruct> all_items = {
{151, "test1"},
{154, "test4"},
{152, "test2"},
{151, "test1"},
{151, "test1"},
{153, "test3"}
};
Library usage
What you're really doing is starting with a collection of items, and partitioning it into two groups. That being the case, I'd at least consider using std::partition
to do the partitioning part:
int main() {
std::unordered_set<int> bad_ids { 151, 152 };
std::vector<mystruct> all_items = {
{151, "test1"},
{154, "test4"},
{152, "test2"},
{151, "test1"},
{151, "test1"},
{153, "test3"}
};
auto part = std::partition(all_items.begin(), all_items.end(),
[&](mystruct const &s) { return bad_ids.find(s.id) != bad_ids.end();});
show("bad items", all_items.begin(), part);
show("Good items", part, all_items.end());
}