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?
teams
being a std::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_i
is a reference to type std::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_it
will be of type std::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_it
will be of type std::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::set
and std::list
is not as convenient as using indexed random access with std::vector
. std::vector
has additional benefits (simple and efficient implementation, continous memory block).
If you use std::vector
s instead of std::set
and std::list
, vek
will be defined as:
typedef std::vector<std::vector<std::vector<std::string>>> vek;
std::list
being a linked list offers some benefits (like being able to add an element in O(1)). std::set
guarentees 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 only std::vector
s 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 the set::set
the elements are already std::string
s.std::set
keeps 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 contains std::string
s and the default sort order for them is alphabetically.std::vector
instead of std::set
like I proposed above, will get you the result you wanted (std::vector
is not sorted automatically).If you want to try using only std::vector
:
Change vek
to:
typedef std::vector<std::vector<std::string>>vek;
And replace the usage of insert
(to add an element to the set) with push_back
to do the same for a vector.