如何随机组合两个数组而不重复C ++中的值

时间:2012-04-19 13:49:25

标签: c++ arrays combinatorics shuffle

我有两个数组:

array1( 'Apple',
        'Pear',
        'Banana',
        'Apricot',
        'Watermelon',
        'Peach',
        'Pineapple',
        'Strawberry',
        'Melon',
        'Pomegranate',
        'Oranges',
        'Tangerine' ); 

tangerineeee的大小..哇!我只是无法帮助它。这很有趣......现在让我们回到第二个阵列。

array2( 'Fruits On Table',
        'Fruits In Basket',
        'Fruits In Fridge' );

我想生成一个列表                  或数组                  或一个字符串 什么可以有橘子的大小...

可以随机合并这两个数组但不重复第一个数组的东西。这将是什么样的:

Tangerine( 'Tangerine - Fruits In Fridge',
           'Apple - Fruits On Table',
           'Pear - Fruits In Basket',
           'Peach - Fruits In Fridge',
           'Apricot - Fruits On Table',
           'Oranges - Fruits In Basket',
           'Melon - Fruits In Fridge',
           'Watermelon - Fruits On Table',
           'Pineapple - Fruits On Table',
           'Pomegranate - Fruits In Basket',
           'Strawberry - Fruits In Fridge',
           'Banana - Fruits In Basket' ); 

如果仔细观察,可以从两个数组中随机选择它们并合并在一起而不重复第一个数组..

那么我怎样才能用C ++做到这一点? 我是C ++的新手

关于它的一点算法也不错。

5 个答案:

答案 0 :(得分:4)

您可以将random_shuffle应用于第一个数组中的元素。然后循环遍历那些,从第二个数组中拾取随机元素。例如,您可以使用uniform_int_distribution生成0,1,2的随机数分布。或者你可以省略第二个数组元素的随机化,然后按顺序选择它们,然后随机输出。

答案 1 :(得分:1)

您可以使用std::map之类的内容,第一个数组中的字符串作为键,组合字符串作为值。即使你的随机数发生器创建的字符串与你已经使用过的字符串相同,它仍然只是地图中的水果之一。

如果您这样做,直到地图中的条目数与水果数相同,那么您将获得所有成果。

答案 2 :(得分:1)

您可以将Fisher-Yates shuffle数字0实现为N,其中Narray1中的项目数,然后合并array1[fyPermutation[i]]处的项目使用array2中的随机项。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <list>
#include <sstream>
#include <iostream>
#include <bitset>
#include <ctype.h>

using namespace std;

const char *array1[] = {
    "Apple", "Pear", "Banana",  "Apricot",
    "Watermelon", "Peach", "Pineapple", "Strawberry",
    "Melon", "Pomegranate", "Oranges", "Tangerine"
};

const char *array2[] = {
    "Fruits On Table", "Fruits In Basket", "Fruits In Fridge"
};

vector<int> random_permutation(int n) {
    vector<int> p(n);
    for (int i = 0; i < n; ++i) {
        int j = rand() % (i + 1);
        p[i] = p[j];
        p[j] = i;
    }
    return p;
}

int main(int argc, const char* argv[]) {
    size_t N1 = sizeof(array1)/sizeof(array1[0]);
    size_t N2 = sizeof(array2)/sizeof(array2[0]);
    vector<int> perm = random_permutation(N1);
    vector<string> res;
    for(int i=0 ; i != N1 ; i++) {
        res.push_back(array1[perm[i]] + string(" - ") + array2[rand() % N2]);
    }
    for(int i=0 ; i != res.size() ; i++) {
        cout << res[i] << endl;
    }
    return 0;
}

答案 3 :(得分:1)

你可以像现实生活中的某个人那样做。您可以将数组视为随机选择的包,并在每次选择后删除该项。你不可能两次拿到水果!如果您不想损坏原始阵列,您可以制作副本并将其用作“包”......

当然,天真地做这些事情有很多性能问题:

Get random element and remove it

How to select a random element in std::set?

...但是如果你不明白它们是什么以及为什么要避免它们,那么直接跳到StackOverflowers提出的复杂的洗牌解决方案似乎有点......可疑。 : - )

答案 4 :(得分:1)

对于array1中的每个字符串,您需要有效地随机播放的内容。这将是一个指针,因此为array1中的每个字符串创建一个并将它们存储在一个数组中 - 您必须将malloc()数组设置为正确的大小以容纳sizeof(array1)指针。

随机改组指针数组是一种常见的算法,可以轻松地将其谷歌化。基本上,取第一个元素并用它上面的随机元素交换它,然后用第二个元素做同样的事情....

然后你有一个随机数组的char *到array1字符串,没有重复。

在shuffling之后,你可以迭代shuffled char *数组,并且对于每一个,通过将shuffled字符串与随机选择的array2字符串连接来组装输出字符串,(你可能想要使用另一个函数来返回char *到随机array2字符串)。在删除任何内容之前,请注意分配正确的空间量来保存输出,包括null char!

你去吧!现在就做。

完成后不要忘记处理()东西。