1

我有两个数组:

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

一个橘子的大小……嗯!我就是忍不住。真是太有趣了……现在让我们回到第二个数组。

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++ 的新手

还有一个关于它的小算法会很好。

4

5 回答 5

4

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

于 2012-04-19T13:59:45.033 回答
1

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

如果您这样做直到地图中的条目数与水果数相同,则您拥有所有水果。

于 2012-04-19T13:55:07.703 回答
1

您可以实现数字零到 的Fisher-Yates 洗牌N,其中N是 中的项目数array1,然后将 的项目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;
}
于 2012-04-19T13:56:53.833 回答
1

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

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

获取随机元素并将其删除

如何在 std::set 中选择随机元素?

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

于 2012-04-19T14:05:21.833 回答
1

您需要一些可以有效地为 array1 中的每个字符串洗牌的东西。这将是一个指针,因此为 array1 中的每个字符串创建一个并将它们存储在一个数组中 - 您必须将 malloc() 数组调整为正确的大小以保存 sizeof(array1) 指针。

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

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

改组后,您可以迭代改组的 char* 数组,并且对于每个数组,通过将改组的字符串与随机选择的 array2 字符串连接来组装输出字符串,(您可能希望使用另一个函数将 char* 返回到随机array2 字符串)。在 strcatting 任何东西之前,请注意分配正确的空间量来保存输出,包括空字符!

给你!现在去做吧。

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

于 2012-04-19T14:19:40.947 回答