I'm trying to write a function which will return vector of set type string which represent members of teams.
A group of names should be classified into teams for a game. Teams should be the same size, but this is not always possible unless n is exactly divisible by k. Therefore, they decided that the first mode (n, k) teams have n / k + 1 members, and the remaining teams have n / k members.
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <list>
typedef std::vector<std::set<std::string>>vek;
vek Distribution(std::vector<std::string>names, int k) {
int n = names.size();
vek teams(k);
int number_of_first = n % k;
int number_of_members_first = n / k + 1;
int number_of_members_remaining = n / k;
int l = 0;
int j = 0;
for (int i = 1; i <= k; i++) {
if (i <= number_of_first) {
int number_of_members_in_team = 0;
while (number_of_members_in_team < number_of_members_first) {
teams[l].insert(names[j]);
number_of_members_in_team++;
j++;
}
}
else {
int number_of_members_in_team = 0;
while (number_of_members_in_team < number_of_members_remaining) {
teams[l].insert(names[j]);
number_of_members_in_team++;
j++;
}
}
l++;
}
return teams;
}
int main ()
{
for (auto i : Distribution({"Damir", "Ana", "Muhamed", "Marko", "Ivan",
"Mirsad", "Nikolina", "Alen", "Jasmina", "Merima"
}, 3)) {
for (auto j : i)
std::cout << j << " ";
std::cout << std::endl;
}
return 0;
}
OUTPUT should be:
Damir Ana Muhamed Marko
Ivan Mirsad Nikolina
Alen Jasmina Merima
MY OUTPUT:
Ana Damir Marko Muhamed
Ivan Mirsad Nikolina
Alen Jasmina Merima
Could you explain me why names are not printed in the right order?
teamsbeing astd::vector<...>supports random access via an index.auto & team_i = teams[i];(0 <= i < teams.size()), will give you an element of the vector.team_iis a reference to typestd::set<std::list<std::string>>.As a
std::set<...>does not support random access via an index, you will need to access the elements via iterators (begin(),end()etc.), e.g.:auto set_it = team_i.begin();.*set_itwill be of typestd::list<std::string>.Since
std::list<...>also does not support random access via an index, again you will need to access it via iterators, e.g.:auto list_it = set_it->begin();.*list_itwill be of typestd::string.This way it is possible to access every set in the vector, every list in each set, and every string in each list (after you have added them to the data structure).
However - using iterators with
std::setandstd::listis not as convenient as using indexed random access withstd::vector.std::vectorhas additional benefits (simple and efficient implementation, continous memory block).If you use
std::vectors instead ofstd::setandstd::list,vekwill be defined as:std::listbeing a linked list offers some benefits (like being able to add an element in O(1)).std::setguarentees that each value is present once. But if you don't really need these features, you could make you code simpler (and often more efficient) if you use onlystd::vectors as your containers.Note: if every set will ever contain only 1 list (of strings) you can consider to get rid of 1 level of the hirarchy, I.e. store the lists (or vectors as I suggested) directly as elements of the top-level vector.
UPDATE:
Since the question was changed, here's a short update:
std::list. So when you iterate on theset::setthe elements are alreadystd::strings.std::setkeeps the elements sorted, and when you iterate it you will get the elements by that sorting order. See the answer here: Is the std::set iteration order always ascending according to the C++ specification?. Your set containsstd::strings and the default sort order for them is alphabetically.Using
std::vectorinstead ofstd::setlike I proposed above, will get you the result you wanted (std::vectoris not sorted automatically).If you want to try using only
std::vector:Change
vekto:And replace the usage of
insert(to add an element to the set) withpush_backto do the same for a vector.