如何每次以不同的顺序打印矢量

时间:2015-08-16 15:04:15

标签: c++ algorithm random vector

我正在尝试制作两个向量。其中vector1(total1)包含一些字符串,vector2(total2)包含一些随机唯一数字(介于0和total1.size()之间 - 1)

我想制作一个打印出total1s字符串的程序,但每回合都会以不同的顺序打印出来。我不想使用迭代器或其他东西,因为我想提高我的问题解决能力。

以下是使程序崩溃的特定功能。

    for (unsigned i = 0; i < total1.size();)
{
    v1 = rand() % total1.size();
    for (unsigned s = 0; s < total1.size(); ++s)
    {
        if (v1 == total2[s])
            ;
        else
        {
            total2.push_back(v1);
            ++i;
        }
    }
}

我非常感谢能得到任何帮助!

2 个答案:

答案 0 :(得分:1)

我可以建议您更改算法吗?因为,即使你当前的一个正确实现(“s”,在你的代码中,必须从0到总 2 .size不是total1.size,如果找到了元素,则中断并生成一个新的随机),它有以下缺点:假设1.000.000元素的向量,你正在尝试最后一个随机数。您在1.000.000中有一个概率找到以前未使用过的随机数。这是一个非常小的数量。最后但是一个数字在1.000.000中的概率为2也很小。总之,您的程序将循环并消耗大量CPU资源。

您最好的选择是关注@NathanOliver建议并查找函数std::shuffle。手册页显示了您正在寻找的实现算法。

另一个简单的算法,有一些优点和缺点,是:

  1. init total2,序列为0,1,2,...,n,其中n为大小total1 - 1
  2. 选择两个随机数i1和i2,范围为[0,n-1]。
  3. 将元素i1和i2交换为total2。
  4. 从(2)重复固定次数“R”。
  5. 该方法允许先验地知道必要步骤并控制最终矢量的“随机性”水平(更大的R更随机)。然而,它的随机性质远远不够。

    另一种方法,在概率分布方面更好:

    1. 填写列表L,编号为0,1,2,...大小为1-1。
    2. 选择0和列表i的大小之间的随机数L - 1。
    3. i列表L中的第L个元素存储在total2中。
    4. L删除此元素。
    5. 从(2)重复,直到collectionView!.autoresizingMask为空。

答案 1 :(得分:1)

如果您只是想要随机播放vector<string> total1,则无需使用vector<int> total2即可执行此操作。以下是基于Fisher–Yates shuffle的实现。

for(int i=n-1; i>=1; i--) {
    int j=rand()%(i+1);
    swap(total1[j], total1[i]);  // your prof might not allow use of swap:)
}

如果您必须使用vector<int> total2,请使用上述算法对其进行随机播放。接下来,您可以使用它从vector<string> result total1创建新的result[i]=total1[total2[i]]