将元素插入列表的任务 - 有点困难
Task with inserting elements to list - tough a little
这只是过去几个问题的延续。
我的函数应该returnstd::vector<std::set<std::string>>
一组名字应该被分类到一个游戏的团队中。团队的规模应该相同,但这并不总是可能的,除非 n 可以被 k 整除。因此,他们决定第一种模式(n,k)队有n/k+1人,其余队有n/k人。
函数接受的字符串向量必须转换为字符串列表。
我需要遍历列表元素并将它们添加到集合中。但是,在列表 中移动时,我需要跳过列表 中已经添加到集合中的元素。在遍历列表之前将列表的第一个元素添加到集合中。
移动是根据最后插入的成员的长度计算的。例如,如果插入 Damir,则 move (shift) 将为 5.
解释:
更新[根据@stefaanv 的建议]:
#include <iostream>
#include <list>
#include <set>
#include <string>
#include <vector>
typedef std::vector<std::set<std::string>> vek;
vek Distribution(const std::vector<std::string>&names, int k) {
vek teams(k);
int num = names.size();
int number_of_first = num % k;
int number_of_members_first = num / k + 1;
int number_of_members_remaining = num / k;
std::list<std::string> lista;
for (int i = 0; i < num; i++)
lista.push_back(names[i]);
auto it = lista.begin();
auto temp = it;
int n = num, new_member = 0, index_list = 0;
for (int i = 0; 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) {
for (int i = 0; i < new_member; i++)
index_list++;
if (index_list > n - 1)
index_list = index_list - n;
while (it != lista.begin())
it--;
for (int i = 0; i < index_list; i++)
it++;
teams[i].insert(*it);
number_of_members_in_team++;
new_member = it->length();
it = lista.erase(it);
n--;
}
} else {
int number_of_members_in_team = 0;
while (number_of_members_in_team < number_of_members_remaining) {
for (int i = 0; i < new_member; i++)
index_list++;
if (index_list > n - 1)
index_list = index_list - n;
while (it != lista.begin())
it--;
for (int i = 0; i < index_list; i++)
it++;
teams[i].insert(*it);
number_of_members_in_team++;
new_member = it->length();
it = lista.erase(it);
n--;
}
}
}
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;
}
正确的输出是:
Ana Damir Mirsad Muhammed
Ivan Merima Nikolina
Alen Jasmina Marko
我在输出中什么也没得到!
我只需要对算法进行简单的修复。我没有任何输出的原因是:
it = lista.erase(it);
n--;
如果我不使用这些代码行,我会得到分别有 4、3 和 3 个名称的 3 个团队,只是名称有误。所以现在我得到了正确数量的团队和正确数量的团队成员。这里唯一的问题仍然是为团队添加正确的名称...
你能给我更好的方法吗?
检查功能中的一个错误:您只检查当前团队中的名称以跳过它,但您应该跳过任何已经放入团队中的名称。
我已经给了你另一个问题的替代方案,所以不需要检查功能(从列表中删除)。
此外,在遍历列表时,您应该考虑到当您到达结尾时,您必须从开头继续。将名称添加 100 次不是一个好的选择。
提示:
- 尝试在注释中添加您的代码应该执行的操作,这样您就可以了解为什么代码无法按预期工作。
- 如果可能,使用 const 引用将 data-structures 传递给函数
- 接下来的轮班数:it->length() 也可以,不用找名字了。
- 您可以轻松避免代码重复,唯一的区别是一个数字。
- i 和 l 具有相同的含义,当你从 0 到 < k 迭代 i 时,它们变得相同。
根据我的评论更改问题中的代码后进行编辑
根据您编辑的代码编写我将如何做的代码(有两个名称与预期输出交换),make_team()
和 Distribution()
正在一起处理数据,因此它们可能是加入了 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;
}
这只是过去几个问题的延续。
我的函数应该returnstd::vector<std::set<std::string>>
一组名字应该被分类到一个游戏的团队中。团队的规模应该相同,但这并不总是可能的,除非 n 可以被 k 整除。因此,他们决定第一种模式(n,k)队有n/k+1人,其余队有n/k人。
函数接受的字符串向量必须转换为字符串列表。
我需要遍历列表元素并将它们添加到集合中。但是,在列表 中移动时,我需要跳过列表 中已经添加到集合中的元素。在遍历列表之前将列表的第一个元素添加到集合中。
移动是根据最后插入的成员的长度计算的。例如,如果插入 Damir,则 move (shift) 将为 5.
解释:
更新[根据@stefaanv 的建议]:
#include <iostream>
#include <list>
#include <set>
#include <string>
#include <vector>
typedef std::vector<std::set<std::string>> vek;
vek Distribution(const std::vector<std::string>&names, int k) {
vek teams(k);
int num = names.size();
int number_of_first = num % k;
int number_of_members_first = num / k + 1;
int number_of_members_remaining = num / k;
std::list<std::string> lista;
for (int i = 0; i < num; i++)
lista.push_back(names[i]);
auto it = lista.begin();
auto temp = it;
int n = num, new_member = 0, index_list = 0;
for (int i = 0; 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) {
for (int i = 0; i < new_member; i++)
index_list++;
if (index_list > n - 1)
index_list = index_list - n;
while (it != lista.begin())
it--;
for (int i = 0; i < index_list; i++)
it++;
teams[i].insert(*it);
number_of_members_in_team++;
new_member = it->length();
it = lista.erase(it);
n--;
}
} else {
int number_of_members_in_team = 0;
while (number_of_members_in_team < number_of_members_remaining) {
for (int i = 0; i < new_member; i++)
index_list++;
if (index_list > n - 1)
index_list = index_list - n;
while (it != lista.begin())
it--;
for (int i = 0; i < index_list; i++)
it++;
teams[i].insert(*it);
number_of_members_in_team++;
new_member = it->length();
it = lista.erase(it);
n--;
}
}
}
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;
}
正确的输出是:
Ana Damir Mirsad Muhammed
Ivan Merima Nikolina
Alen Jasmina Marko
我在输出中什么也没得到!
我只需要对算法进行简单的修复。我没有任何输出的原因是:
it = lista.erase(it);
n--;
如果我不使用这些代码行,我会得到分别有 4、3 和 3 个名称的 3 个团队,只是名称有误。所以现在我得到了正确数量的团队和正确数量的团队成员。这里唯一的问题仍然是为团队添加正确的名称...
你能给我更好的方法吗?
检查功能中的一个错误:您只检查当前团队中的名称以跳过它,但您应该跳过任何已经放入团队中的名称。
我已经给了你另一个问题的替代方案,所以不需要检查功能(从列表中删除)。
此外,在遍历列表时,您应该考虑到当您到达结尾时,您必须从开头继续。将名称添加 100 次不是一个好的选择。
提示:
- 尝试在注释中添加您的代码应该执行的操作,这样您就可以了解为什么代码无法按预期工作。
- 如果可能,使用 const 引用将 data-structures 传递给函数
- 接下来的轮班数:it->length() 也可以,不用找名字了。
- 您可以轻松避免代码重复,唯一的区别是一个数字。
- i 和 l 具有相同的含义,当你从 0 到 < k 迭代 i 时,它们变得相同。
根据我的评论更改问题中的代码后进行编辑
根据您编辑的代码编写我将如何做的代码(有两个名称与预期输出交换),make_team()
和 Distribution()
正在一起处理数据,因此它们可能是加入了 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;
}