我有此函数返回c + +中的随机数组:
int* randomArray(int countOfRows){
int test1 [countOfRows] = {};
int insertValue;
int check;
for (int n=0; n < countOfRows; ++n){
srand(time (NULL) );
while (test1[n] == NULL){
insertValue = (rand () %100 + 1 );
for(int i = 0; i < countOfRows; i++){
if (test1[i] == insertValue){
check = 1;
break;
}
else{
check = 0;
}
}
if (check == 0){
test1[n] = insertValue;
}
}
}
return test1;
}
我怎么称呼那个数组?
int *和int []有什么区别
谢谢 :)
最佳答案
您的代码有四个重大问题,其中一个很关键,一个是非标准的且依赖于实现的,还有两个一般的算法问题。
首先,最重要的是,您要返回一个自动变量的地址,这意味着它既无用,又会调用未定义的行为来由调用者取消引用。在函数顶部声明的是:
int test1 [countOfRows] = {};
它本身就提出了第二点,它是非标准的,这有两个原因:C ++标准不支持可变长度数组,并且据推断,同样不支持“相同”的初始化。后来...
return test1;
函数的调用者将收到一个地址,但是该地址没有用。它不再处理任何具体的问题,因为一旦函数返回,
test1
就不再存在。这可以通过多种方法来解决,考虑到这是C ++,最简单的方法是使用std::vector<int>
,它支持价值回报。两个重要的算法问题是
您的
srand
种子不应位于for循环中。实际上,如果您使用的是srand
和rand
,则播种应该在整个过程中进行一次。如果您只是使用其他算法,则无需进行详尽搜索以查看是否已经使用当前的随机选择来避免重复,这一点我将在后面介绍。
因此,对您的代码最简单的修复方法是:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
std::vector<int> randomArray(int countOfRows)
{
std::vector<int> test1(countOfRows);
int check = 0;
for (int n=0; n < countOfRows; ++n)
{
while (test1[n] == 0)
{
int insertValue = (rand () %100 + 1 );
for(int i = 0; i < countOfRows; i++)
{
if (test1[i] == insertValue){
check = 1;
break;
}
else{
check = 0;
}
}
if (check == 0){
test1[n] = insertValue;
}
}
}
return test1;
}
int main()
{
std::srand(static_cast<unsigned>(std::time(NULL)));
std::vector<int> vec = randomArray(20);
for (auto x : vec)
std::cout << x << ' ';
std::cout.put('\n');
}
输出(可变)
8 50 74 59 31 73 45 79 24 10 41 66 93 43 88 4 28 30 13 70
有限集算法
您实际上要在此处生成的是1..100范围内的有限整数集。即,没有使用重复的值,并且返回的项目数也可以是1..100之内的任何值。为此,请考虑以下算法:
在
std::vector<int>
中生成1..100的序列使用标准库中的伪随机数生成器,使用
std::shuffle
随机排序序列将结果向量的大小调整为要返回的元素数。
关于上面的#3,请考虑一个小示例,假设您只需要10个元素。最初,您将构建一个如下所示的序列向量:
1 2 3 4 5 6 7 8 9 10 11 12 13... ...99 100
现在,您可以使用
std::shuffle
和伪随机生成器(如std::mt19937
)(为简洁起见,显示前20个元素)对向量进行混洗:48 39 31 44 68 84 98 40 57 76 70 16 30 93 9 51 63 65 45 81...
现在,您只需将向量的大小调整为所需大小即可,在本例中为10个元素:
48 39 31 44 68 84 98 40 57
那就是你的结果。如果听起来很复杂,您可能会惊讶地发现它实际上只需要很少的代码:
码
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
#include <random>
std::vector<int> randomSequence100(std::size_t count)
{
if (count > 100)
count = 100;
static std::random_device rd;
std::vector<int> result(100);
std::iota(result.begin(), result.end(), 1);
std::shuffle(result.begin(), result.end(), std::mt19937(rd()));
result.resize(count);
return result;
}
int main()
{
// run twenty tests of random shuffles.
for (int i=0; i<20; ++i)
{
auto res = randomSequence100(20);
for (auto x : res)
std::cout << x << ' ';
std::cout.put('\n');
}
}
输出量
27 71 58 6 74 65 56 37 53 44 25 91 10 86 51 75 31 79 18 46
6 61 92 74 30 20 91 89 64 55 19 12 28 13 5 80 62 71 29 43
92 42 2 1 78 89 65 39 37 64 96 20 62 33 6 12 85 34 29 19
46 63 8 44 42 80 70 2 68 56 86 84 45 85 91 33 20 83 16 93
100 99 4 20 47 32 58 57 11 35 39 43 87 55 77 51 80 7 46 83
48 39 31 44 68 84 98 40 57 76 70 16 30 93 9 51 63 65 45 81
32 73 97 83 56 49 39 29 3 59 45 89 43 78 61 5 57 51 82 8
21 46 25 29 48 37 77 74 32 56 87 91 94 86 57 67 33 9 23 36
27 46 66 40 1 72 41 64 53 26 31 77 42 38 81 47 58 73 4 11
79 77 46 48 70 82 62 87 8 97 51 99 53 43 47 91 98 81 64 26
27 55 28 12 49 5 70 94 77 29 84 23 52 3 25 56 18 45 74 48
95 33 25 80 81 53 55 11 70 2 38 77 65 13 27 48 40 57 87 93
70 95 66 84 15 87 94 43 73 1 13 89 44 96 10 58 39 2 23 72
43 53 93 7 95 6 19 89 37 71 26 4 17 39 30 79 54 44 60 98
63 26 92 64 83 84 30 19 12 71 95 4 81 18 42 38 87 45 62 70
78 80 95 64 71 17 14 57 54 37 51 26 12 16 56 6 98 45 92 85
89 73 2 15 43 65 21 55 14 27 67 31 54 52 25 72 41 6 85 33
4 87 19 95 78 97 27 13 15 49 3 17 47 10 84 48 37 2 94 81
15 98 77 64 99 68 34 79 95 48 49 4 59 32 17 24 36 53 75 56
78 46 20 30 29 35 87 53 84 61 65 85 54 94 68 75 43 91 95 52
上面的每一行都是从1..100序列中取出的二十个元素的集合。没有任何一行重复(请检查是否要重复)。
警告
对于较小的域或较大的域中的大型结果集,此技术都非常有效。但是它有其考虑的局限性。
例如:一旦您的潜在域达到有效点的大小(例如1 ... 1000000中的数字),并且只需要较小的结果集(例如,不大于100个元素),则最好使用
std::unordered_set
和迭代探测,类似于您现在正在做的事情。您使用的技术完全取决于您的性能目标和使用模式。反例:如果您希望从一百万个元素的域中混入五十万个唯一元素,则加载/混洗/调整大小技术会很好地工作。
最终,您必须决定并采取措施进行确认。
有关此处使用的某些事物的一些有用链接(在此站点添加书签,因为它绝对是有关C ++信息的黄金):
std::vector
std::iota
std::random_device
std::mt19937
std::shuffle
关于c++ - 调用和打印函数,它们在C++中返回数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45912418/