集合插入元素的向量
Vector of set insert elements
我正在尝试编写一个函数,它将 return 表示团队成员的集合类型字符串的向量。
一组名字应该被分类到一个游戏的团队中。团队的规模应该相同,但这并不总是可能的,除非 n 可以被 k 整除。因此,他们决定第一种模式(n,k)队有n/k+1人,其余队有n/k人。
#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
你能解释一下为什么名字没有按正确的顺序打印吗?
teams
作为 std::vector<...>
支持通过索引进行随机访问。
auto & team_i = teams[i];
(0 <= i < teams.size()),会给你一个向量的元素。 team_i
是对类型 std::set<std::list<std::string>>
的引用。
由于 std::set<...>
不支持通过索引进行随机访问,您需要通过迭代器(begin()
、end()
等)访问元素,例如:auto set_it = team_i.begin();
。 *set_it
将是 std::list<std::string>
.
类型
由于 std::list<...>
也不支持通过索引进行随机访问,因此您需要再次通过迭代器访问它,例如:auto list_it = set_it->begin();
。 *list_it
将是 std::string
.
类型
这样就可以访问向量中的每个集合、每个集合中的每个列表以及每个列表中的每个字符串(在将它们添加到数据结构之后)。
但是 - 在std::set
和std::list
中使用迭代器不如在std::vector
中使用索引随机访问方便。 std::vector
有额外的好处(简单高效的实现,连续的内存块)。
如果您使用 std::vector
s 而不是 std::set
和 std::list
,vek
将被定义为:
typedef std::vector<std::vector<std::vector<std::string>>> vek;
std::list
作为链表有一些好处(比如能够在 O(1) 中添加元素)。 std::set
保证每个值都出现一次。
但是,如果您真的不需要这些功能,如果您只使用 std::vector
作为容器,则可以使代码更简单(通常更高效)。
注意:如果每个集合只包含 1 个列表(字符串),您可以考虑去掉 1 级层次结构,即将列表(或我建议的向量)直接存储为 top-level 向量的元素。
更新:
由于问题已更改,这里有一个简短的更新:
- 在我上面的回答中,忽略所有提到的
std::list
。所以当你迭代 set::set
时,元素已经是 std::string
s.
- 名称与您预期的顺序不一致的原因:
std::set
保持元素排序,当你迭代它时,你将按照该排序顺序获取元素。请在此处查看答案:Is the std::set iteration order always ascending according to the C++ specification?。您的集合包含 std::string
,它们的默认排序顺序是按字母顺序排列。
使用 std::vector
而不是我上面建议的 std::set
,将会得到你想要的结果(std::vector
不会自动排序)。
如果你只想尝试使用 std::vector
:
将 vek
更改为:
typedef std::vector<std::vector<std::string>>vek;
并将 insert
的用法(将元素添加到集合中)替换为 push_back
以对矢量执行相同的操作。
我正在尝试编写一个函数,它将 return 表示团队成员的集合类型字符串的向量。
一组名字应该被分类到一个游戏的团队中。团队的规模应该相同,但这并不总是可能的,除非 n 可以被 k 整除。因此,他们决定第一种模式(n,k)队有n/k+1人,其余队有n/k人。
#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
你能解释一下为什么名字没有按正确的顺序打印吗?
teams
作为 std::vector<...>
支持通过索引进行随机访问。
auto & team_i = teams[i];
(0 <= i < teams.size()),会给你一个向量的元素。 team_i
是对类型 std::set<std::list<std::string>>
的引用。
由于 std::set<...>
不支持通过索引进行随机访问,您需要通过迭代器(begin()
、end()
等)访问元素,例如:auto set_it = team_i.begin();
。 *set_it
将是 std::list<std::string>
.
由于 std::list<...>
也不支持通过索引进行随机访问,因此您需要再次通过迭代器访问它,例如:auto list_it = set_it->begin();
。 *list_it
将是 std::string
.
这样就可以访问向量中的每个集合、每个集合中的每个列表以及每个列表中的每个字符串(在将它们添加到数据结构之后)。
但是 - 在std::set
和std::list
中使用迭代器不如在std::vector
中使用索引随机访问方便。 std::vector
有额外的好处(简单高效的实现,连续的内存块)。
如果您使用 std::vector
s 而不是 std::set
和 std::list
,vek
将被定义为:
typedef std::vector<std::vector<std::vector<std::string>>> vek;
std::list
作为链表有一些好处(比如能够在 O(1) 中添加元素)。 std::set
保证每个值都出现一次。
但是,如果您真的不需要这些功能,如果您只使用 std::vector
作为容器,则可以使代码更简单(通常更高效)。
注意:如果每个集合只包含 1 个列表(字符串),您可以考虑去掉 1 级层次结构,即将列表(或我建议的向量)直接存储为 top-level 向量的元素。
更新:
由于问题已更改,这里有一个简短的更新:
- 在我上面的回答中,忽略所有提到的
std::list
。所以当你迭代set::set
时,元素已经是std::string
s. - 名称与您预期的顺序不一致的原因:
std::set
保持元素排序,当你迭代它时,你将按照该排序顺序获取元素。请在此处查看答案:Is the std::set iteration order always ascending according to the C++ specification?。您的集合包含std::string
,它们的默认排序顺序是按字母顺序排列。
使用std::vector
而不是我上面建议的std::set
,将会得到你想要的结果(std::vector
不会自动排序)。
如果你只想尝试使用 std::vector
:
将 vek
更改为:
typedef std::vector<std::vector<std::string>>vek;
并将 insert
的用法(将元素添加到集合中)替换为 push_back
以对矢量执行相同的操作。