One wrong thing in your check function: you only check the names in the current team to skip that, but you should skip any name that was already put in a team.
I already gave you an alternative on another question, so the check function isn’t needed (erasing from the list).
Also, when iterating over a list, you should take into account that when you reach end, you must continue at begin. Adding the names a 100 times isn’t a good alternative.
Hints:
- try to put in comments what your code is supposed to do so you and we can see why the code doesn’t work as expected.
- When possible, use const reference to pass data-structures to functions
- For the number of next shifts: it->length() works too, no need to look for the name.
- You can easily avoid the code duplication, the only difference is one number.
- i and l have the same meaning and when you iterate i from 0 to < k, they become the same.
EDIT after changing code in the question based on my comments
Code how I would do it based on your edited code (there are two names switched with the expected output), make_team()
and Distribution()
are working together on the data, so they could be joined in a class:
#include <iostream>
#include <list>
#include <set>
#include <string>
#include <vector>
// data structure for result
typedef std::vector<std::set<std::string>> ResultType;
// put players in one team according to shift algorithm (shifts is length of name of last player) to make more random
// list_players and it_players are references and are being changed in this function
std::set<std::string> make_team(std::list<std::string>& list_players, std::list<std::string>::iterator& it_players,int size)
{
std::set<std::string> team;
int number_shifts = 0;
int number_of_members_in_team = 0;
while (number_of_members_in_team < size)
{
// shift to new selection (rotate: end becomes begin)
for (int i = 0; i < number_shifts - 1; i++)
{
it_players++;
if (it_players == list_players.end()) it_players = list_players.begin();
}
// move to team by inserting and deleting from list
team.insert(*it_players);
number_of_members_in_team++;
number_shifts = it_players->length(); // distribute algorithm: shift number of times as length of name of last chosen player
it_players = list_players.erase(it_players);
if (list_players.empty()) // just in case
return team;
}
return team;
}
// distribute players to given number of teams
ResultType Distribution(const std::vector<std::string>&names, int number_teams) {
// init
ResultType teams(number_teams);
int number_players = names.size();
int number_of_first = number_players % number_teams;
int number_of_members = number_players / number_teams + 1; // adjusted after number_of_first
std::list<std::string> list_players(names.begin(), names.end());
auto it_players = list_players.begin();
// do for all teams
for (int tm = 0; tm < number_teams; ++tm)
{
if (tm == number_of_first) // adjust because not all teams can have the same size, so first teams can be larger by 1
number_of_members--;
teams[tm] = make_team(list_players, it_players, number_of_members);
if (list_players.empty())
return teams;
}
return teams;
}
// test harnass
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;
}
5
solved Task with inserting elements to list – tough a little