从2D阵列中随机选择而无需重复

时间:2013-09-06 18:56:09

标签: c++ arrays

我正在使用CPP进行二十一点游戏,但我仍然坚持如何从我的[4] [13]阵列中随机选择一个元素而不重复它并且不会改变阵列的顺序。在VisualStudio中工作。到目前为止,我只能找到如何使用1-D阵列做到这一点的答案。有人有建议吗?

8 个答案:

答案 0 :(得分:3)

2D阵列很容易被认为是一维阵列。你只需要做一些数学运算。

如果您的解决方案适用于52个元素的1D数组(随机排序值为0-51的新数组)。执行以下操作:

  1. 生成随机元素,让我们称之为R(0到51之间)。
  2. 现在,将该数字转换为您的2D阵列系统。 (x,y的形式)
    1. x = R / 13
    2. y = R % 13

答案 1 :(得分:2)

使用std::random_shufflevector<int> v随机随机播放vector(例如0-51)。由于random_shuffle对给定的向量进行了混洗,v现在是您随机改组的向量。

v.back()返回向量中的最后一个元素。因此,以下代码返回向量中的最后一个元素(k),然后将其删除。它还会将其转换为double,以便您可以计算k/13

double k = static_cast<double>(v.back());
v.pop_back();

现在,由于您的矩阵是4x13,因此k元素(行主要)位于行floor(k/13)和列k%13

答案 2 :(得分:1)

嗯,一种方法是在数组的元素中添加一个bool字段,当数组的元素被选中时,将其设置为true。然后在将来的选择中,检查bool是否为true,如果是,则生成另一个随机元素。可能不是最有效但很简单。

有了这个,您还可以轻松创建一个迭代数组的方法,并将所有bool字段设置为false以模拟随机播放。

答案 3 :(得分:1)

我建议你强烈考虑使用std::deque<T>容器。一个双端队列来表示牌组本身,然后你可以在你处理它时推出并弹出“牌”。

答案 4 :(得分:1)

附注:不要对数字52进行硬编码:你可能想要在同一阵列中混洗多个套牌。在二十一点赌场的游戏中经常使用二十一点“鞋子”中的多个套牌,特别是每个鞋子的4个套牌是相当普遍的。这对条件概率具有重要意义:面朝上卡和面朝下卡之间的相关性较小。你不会想要单独洗牌52张牌,你需要洗牌整个N * 52牌的鞋子。其他答案中提出的算法适用于3-D阵列以及2-D阵列,只需稍作修改。

答案 5 :(得分:0)

我一直喜欢的一种方法是采用2d数组,然后生成2个坐标进行交换。这样做n次,然后您可以使用一些for loops迭代2D数组。

答案 6 :(得分:0)

我宁愿使用包含所有卡片的列表。如果你坚持使用[4]套件[13]作为数字的二维数组,答案就是简单地制作套牌并且永远不改变值,但是使数组变量成为布尔值。

我写伪代码。

initialize cardsselected to zero

Choose Card
        Randomly select 2 numbers 1 will be 0-3 and the other 0-12. 
        If the array at [random suite][random number] is not false 
             choose it 
             increment cardsselected 
             set value to false
             return true
        else if cardsselected  equals 52 return false
        else 
            run chooseCard() 
            return true

这只是一个解决方案。 非常优化,可能需要永远。

优化它。

你可以保留你的二维阵列来保持卡片只是生成随机数。要优化随机数生成,您可以创建一个随机数列表1-52并从中随机选择。然后删除从列表中选取的号码。

答案 7 :(得分:0)

有一个简单的解决方案涉及使用素数。如果在数组中采用随机初始索引(为简单起见,让它成为一维数组),然后将此索引增加一个大于数组长度的素数,并在除以数组长度后仅获取提醒,您将获得一个随机非重复指数序列。

这样的事情:

#include <cstdlib>
#include <iostream>
#include <time.h>

const int Cols = 4;
const int Rows = 13;
const int N = Cols * Rows;

const int NPrimes = 12;
const int primes[NPrimes] = {59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107};

int prime = primes[0];
int index = 0;

void shuffle()
{
    srand(time(NULL)); // Random seed
    prime = primes[rand() % NPrimes]; // Get random prime number
    index = rand() % N; // Get random first index
}

// Compute next index in sequence
int nextIndex(int index)
{
    return (index + prime) % N;
}

int _tmain(int argc, _TCHAR* argv[])
{
    shuffle();

    for (int i = 0; i < N; i++) {
        int col = index / Rows;
        int row = index % Rows;
        std::cout << "[" << col << ", " << row << "] ";
        index = nextIndex(index);
    }
    std::cout << std::endl;
    return 0;
}

在N次迭代之后,序列将重复自然,显然。