
数组的随机输出与随机数组的产生.pdf
6页数组的随机输出,与随机数组的产生 那天群里有位朋友问了一个对给定数组的随机数组的输出问题, 我的第一反应当 然是产生随机数、然后判断是否产生过、然后赋值、最后输出当然群里其他的 朋友也几乎都是这么想的我之前也没有认真去想过还有没有其他的解决办法 但始终觉得这样产生一个再判断比较,太浪费时间了,数组元素少的时候还好, 但数组元素比较多的时候应该就会很“耗时” 对于给定数组 a[n]的随机输出,学过程序的人就很容易想到用一个循环产生 0— (n-1)之间的随机数(设为 T),然后判断这个数字之前是否已经产生过,如 果没有产生就将 a[T]的值赋给另一个与 a 数组元素相等的数组(设为 b 数组), 如果判断之前已经产生过就重新产生,直到没有产生再赋值 假设产生的随机数为 T, 有两种方法可以达到随机输出 1、在循环中产生随机数,在判断没有产生过这个随机数的情况下,把数组 a[T] 顺序的赋值给 b 数组 2、在循环中产生随机数,在判断没有产生过这个随机数的情况下,顺序的把数 组 a 赋值给数组 b[T] 总觉得这种方法效率不高,但以前也没有想出其他方法,最近想到一个方法,我 觉得这种方法效率更高,我暂且称它为“漏斗法”,简单的将思路描述如下: 定义一个与数组 a[n]等大的数组 b[n] 第 1 次循环产生一个 0——n-1 之间的随机数 T1, 然后将 a[T1]的值赋给 b[1] (即 b[1]=a[T1]),然后我们就将 a[T1]这个数“漏掉”,a[T1]=a[n-1] 第 2 次循环产生一个 0——n-2 之间的随机数 T2,然后将 a[T2]的值赋给 b[2](即 b[2]=a[T2]),然后将 a[T2]这个元素“漏掉” ,a[T2]=a[n-2] ............. ........... 第 n-2 次循环产生一个 0——2 之间的随机数 Tn-2,然后将 a[Tn-2]的值赋给 b[n-2](即 b[n-2]=a[Tn-2]),然后将 a[Tn-2]这个元素“漏掉” ,a[Tn-2]=a[2] 第 n-1 次,将 a 数组的第一个元素赋值给 b 的最后一个元素 文字功底不行啊。
写起来比较费劲,看起来也比较费力 下面用图片来解释下这个过程,可能会更清楚 数组 a[9],数组中的元素如下表 声明一个 b[9](默认元素值全为 0)数组作为随机输出的数组 第 1 次循环产生 0—9 之间的随机数,假设为 3 b[0]=a[3]; 把 a[3]“漏掉” a[3]=a[9] 此时数组 a 中的元素变为 b 数组 第二次循环产生 0—8 之间的随机数,假设为任然产生 3 b[1]=a[3]; 把 a[3]漏掉 a[3]=a[8] 此时数组 a 中的元素变为 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 4 5 6 7 8 9 10 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 4 5 6 7 8 9 10 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 4 0 0 0 0 0 0 0 0 0 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 10 5 6 7 8 9 10 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 4 0 0 0 0 0 0 0 0 0 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 10 5 6 7 8 9 10 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 4 10 0 0 0 0 0 0 0 0 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 9 5 6 7 8 9 10 第 3 次产生 0—7 之间的随机数,假设为 7 b[2]=a[7]; 漏掉 a[7] a[7]=a[7] 此时数组 a 为 第 4 次产生 0—6 之间的随机数,假设为 0 b[3]=a[0]; 漏掉 a[0] a[0]=a[6] 此时数组 a 为 依次类推 。
直到剩下最后一个 a[1],直接将 b[9]=a[1] 就将数组进行了随机输出 上面列出了几个“特殊的位置”,起始位置、最大有效位置(比如第 1 次中的 a[9],第 2 次中的 a[8],第 3 次中的 a[7]….)、前后产生相同随机数的位置,但 是处理方法是一样的,所以也就不叫特殊位置了 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 9 5 6 7 8 9 10 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 4 10 8 0 0 0 0 0 0 0 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 9 5 6 7 8 9 10 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 1 2 3 9 5 6 7 8 9 10 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 4 10 8 1 0 0 0 0 0 0 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 7 2 3 9 5 6 7 8 9 10 如果你数组 a 中的数据其他地方还需要, 可以先做一分拷贝, 用拷贝数组来 完成这个操作。
以下是 c 语言写的上述两种方法的程序(写的不精简,可以多多指点) /////////判断法 #include #define member 1000 main() { int a[member],b[member],c[member],i,j,k,temp,flag,num=0; //a 数组是要随机输出的源数组,b 数组装产生过的随机数方便做比较 //c 数组做输出数组 //i 做循环产生随机数,j 循环判断是否产生过这个随机数,k 计数已经产生过 的有效随机数 //flag 标记是否已经产生过这个随机数,分别做不同的处理 //num 记录产生的随机数的次数(包括无效重复的在内) for(i=0;i #define member 10 main() { int i,temp,a[member],b[member],num=0; for(i=0;i 当然顺着这个思路也就可以产生随机数组了,比如你要产生一个含 10 个元 素的随机数组,数组元素在 100 以内,就可以申明 a[100]={0,1,2……99}然后用 该方法循环 10 次,产生 10 个不重复的随机数组。
