我有这个函数在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;
}
答案 0 :(得分:4)
您的代码有四个重要问题,其中一个是关键问题,一个是非标准问题,依赖于实现问题,以及两个一般算法问题。
首先,最重要的是,您将返回自动变量的地址,这意味着它既无用又会调用未定义的行为以便调用者取消引用。声明在函数顶部的是:
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>
std::shuffle
关于上面的#3,考虑一个小例子,假设你只想要十个元素。最初,您构建一个如下所示的序列向量:
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...
现在,您只需将向量调整到所需的大小,在本例中为十个元素:
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
上面的每一行都是一组20个元素,取自1..100的序列。没有单行有重复(检查是否需要)。
<强>买者强>
此技术适用于较小域或来自较大域的大型结果集。但它有其限制需要考虑。
例如:一旦您的潜在域达到了显着大小的点(例如,数字在1 ... 1000000中)并且您只想要小的结果集(例如,不超过100个元素),那么您的状态会更好使用std::unordered_set
和迭代探测类似于您现在正在做的事情。您使用的技术完全取决于您的性能目标和使用模式。
反例:如果你想要从一个百万元素域中移植50万个唯一元素,那么load / shuffle / resize技术就可以正常工作。
最终,你必须做出决定并进行衡量以确认。
这里使用的一些有用的链接(将此网站加入书签,因为它是绝对的 gold 以获取有关C ++的信息):
答案 1 :(得分:0)
从我看来,这个功能有问题。
它返回test1的点,它在栈中分配,在randomArray的范围之外是无效的。
因此,如果你改为malloc,这是在堆中分配的,那么当它超出randomArray的范围时它仍然有效。
int *test1 = (int*) malloc(countOfRows* sizeof(int));
你可以使用test1 [x]来获取每个int的值,你肯定应该知道test1的长度是countOfRows。
请勿忘记在未使用时删除此点...
调用此数组很简单
int* values = randomArray(1000);
printf("%d\r\n",values[0]);
答案 2 :(得分:0)
在函数randomArray()中将test1 []声明为静态int []。 使用指针返回数组, &#34; return test1&#34; 在main函数中使用指针来访问返回值 &#34; int * ptr = randomArray(n)&#34;