随机生成一个没有重复元素的枚举数组 (C++)
Random generating a array of enum with no repeat elements (C++)
我正在尝试生成一个没有相同元素的枚举数组,但我所做的仍然给了我重复的元素
const int MAXNO = 6;
enum Fruit {Durian, Papaya, Apple, Orange, Mango, Jackfruit, Strawberry};
int main ()
{
srand (time (NULL));
int size = rand () % 6 + 1;
Fruit f [size];
cout << "Size: " << size << endl;
for (int i = 0; i < size; i++)
{
f[i] = static_cast <Fruit>(rand() % MAXNO);
for (int j = 0; j < i; j++)
{
do
{
f[i] = static_cast <Fruit>(rand() % MAXNO);
}while(f[i] == f[j]);
}
cout << f[i] << endl;
}
}
我做错了什么?
您的内部循环旨在检查其他数组元素是否存在重复项,但一旦一个元素不是重复项,您就会提前终止检查。换句话说,您不搜索重复项,而是搜索非重复项。
假设i
是 2,f[0]
是Apple
,f[1]
是Orange
。
内部循环启动,j
为 0。
f[i] = static_cast <Fruit>(rand() % MAXNO);
创建一个Orange
。它应该被检测为重复项,但事实并非如此。
怎么来了?
这是因为在do...while
条件下,您将f[2]
与f[0]
进行比较。它们不相等,因此循环终止。
根据您原始方法,快速解决此问题的是比较所有元素的相等性,理想情况下在单独的函数中:
bool exists(Fruit* begin, Fruit* end, Fruit fruit)
{
for (Fruit* iter = begin; iter != end; ++iter)
{
if (*iter == fruit)
{
return true;
}
}
return false;
}
然后将循环更改为如下所示的内容:
for (int i = 0; i < size; i++)
{
bool duplicate = false;
do
{
f[i] = static_cast <Fruit>(rand() % MAXNO);
duplicate = exists(f, f + i, f[i]);
} while (duplicate);
}
但是这个解决方案仍然存在一些问题,最严重的(在我看来)是循环终止条件取决于随机运气。从理论上讲,该程序可能会循环很长时间甚至永远。
更好的设计是使用老师显然不允许您使用的所有标准C++功能(安全容器和预定义算法),并重新考虑整个程序逻辑。其他答案和评论已经充分涵盖了这一点。
获取数组的枚举长度和初始值为 0,并且对于每个随机枚举生成,检查该数组中的索引为 0,如果为 true,则使该数组上的枚举索引为 1。
获取枚举大小的数组长度 并以 0 开头
int produced_value[MAXNO] = {0}; //be new array
-------------------------
| 0 | 0 | 0 | 0 | 0 | 0 |
-------------------------
这个数组显示了哪个枚举以前产生过。 每次生成随机枚举并希望在检查该数组之前不生成枚举时。如果该数组中的索引为零,则之前未生成且不重复元素使用它并更新数组。
例如
int a;
while(produced_value[(a = rand() % MAXNO)]); //this loop find a that value in produced_value is 0
/* if a == 2 then should update array
-------------------------
| 0 | 0 | 1 | 0 | 0 | 0 |
---------~~~-------------
*/
produced_value[a] = 1; // mark 'a' as produced
//Then use Unique int in the enum range
f[i] = static_cast <Fruit>(a);
首先,不要创建一个可变长度的数组,只使用 vector:
果实 f [大小];
枚举类型在这里无关紧要,所以要解决你的问题,你可以创建一个包含所有可能的 int 值的向量,然后洗牌向量(实时示例):
#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
const int MAXNO = 6;
int main ()
{
std::vector<int> v;
v.reserve(MAXNO);
for (int i = 0; i < MAXNO; ++i)
{
v.push_back(i);
}
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
for (auto& e: v)
{
std::cout << e << " ";
}
}
3 4 0 1 2 5
如果您从集合中随机选择一个元素,然后使该元素准备好再次拾取,则获得重复项是相当合理的。
我建议另一种办法。为什么不先随机排序枚举数组,然后选择第一个size
元素?通过这种方式,您不会获得重复项,并且始终以随机顺序排列第一个size
元素。 另请注意,您有7
枚举,这意味着MAXNO
应该7
否则像int size = rand () % MAXNO;
这样的表达式永远不会返回6
这是列表Strawberry
中的有效枚举。
如下所示,某些东西应该可以工作:
#include <iostream>
#include <chrono>
using namespace std;
const int MAXNO = MAXNO*2;
enum Fruit {Durian, Papaya, Apple, Orange, Mango, Jackfruit, Strawberry};
int main ()
{
srand (time (NULL));
Fruit ff [Strawberry+1] = {Durian, Papaya, Apple, Orange, Mango, Jackfruit, Strawberry};
const int NIT = 7;
for(int i=0 ; i < NIT ; i++ ){
const int ii = (rand() % MAXNO);
const int jj = (rand() % MAXNO);
swap(ff[ii],ff[jj]);
}
//simply output the firse `size` element
//from the randomly ordered array.
const int size = rand () % MAXNO;
for (int i=0;i<size;i++)
cout<<ff[i]<<endl;
}
您可以使用以下代码: 如果您对此有任何问题,请告诉我
enum Fruit {Durian, Papaya, Apple, Orange, Mango, Jackfruit, Strawberry};
私有标准::矢量 ::RanomFruit() { 自动基本列表 = 新列表 {水果::D urian, 水果::P apaya
, 水果::苹果, 水果::橙子, 水果::芒果, 水果::菠萝蜜, 水果::草莓};auto fruitArray = std::vector<Fruit>(7);
Random *random = new Random();
for (int i = 0; i <= 6; i++)
{
int randNumber = random->Next(6 - i);
fruitArray[i] = baseList[randNumber];
baseList->RemoveAt(randNumber);
}
return fruitArray;
}
- 在 C++ 中输出枚举类类型的向量元素
- 如何使用谷歌测试检查两个枚举类元素的相等性?
- std::初始值设定项列表来自现有的 std::array,而不枚举每个元素
- C++:如何将枚举元素设置为无限?
- 正确使用枚举元素
- 如何递归枚举每个元素都有上限的所有可能的数组
- 随机生成一个没有重复元素的枚举数组 (C++)
- 结构元素C 的枚举
- 以编程方式推断出枚举的大小,独立于其元素的价值
- 是否可以定义一个宏来定义枚举类和返回枚举元素计数的 GetCount() 方法
- 如何使用枚举元素创建对象
- 使用对其他枚举值的操作定义枚举元素值
- 宣布枚举以及是否在其元素上
- 以最新的C 的类型安全方式从枚举中随机选择元素
- 如何使用 libclang 获取枚举元素的数值?
- 在编译时获取枚举类大小,而无需定义其他元素
- 枚举元素定义
- 如何静态断言枚举元素的值
- 如何在 c++ 中从枚举返回随机元素
- 用于将枚举元素名称和值保存到文件的 C++ 宏