为了初始化一个不含有重复数字的数组,有几种不同的方式。
第一种、查表法
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int a[100],i, j;
int b[101] = { 0 };
srand(time(NULL));
for (i = 0; i < 100; )
{
j = (rand() % 100 )+ 1;
if (b[j ]== 0)
{
a[i] = j;
b[j ] = 1;
i++;
}
}
for (i = 0; i < 100; i++)
printf("a[%d]=%d\n", i, a[i]);
return 0;
}
查表法的局限性体现在取值范围多少,就要取多大空间的数组用来查表使用。如果需要更大的取值范围,那么需要的内存就更大。
第二种、比较法
void Init_Array(int* br, int n)
{
assert(br != nullptr && n > 0);
int i = 0;
while (i < n)
{
int tmp = rand() % n + 1;
int j = 0;
while (j < i && tmp != br[j])
{
++j;
}
if (j == i)
{
br[i] = tmp;
++i;
}
}
}
比较法的缺点更加明显,如果重复的值比较多,对比次数比较多,相对来说时间复杂度就比较大。
第三种、哈希函数法
#include<stdio.h>
#include<stdlib.h>
#define ARSIZE 10 //宏定义数组大小,存储10个元素
#define HASHSIZE 13 //宏定义哈希函数大小比数组大小大,一般为素数为了避免冲突
int Hash(int key)
{
return key % HASHSIZE;//取余
}
int Inc(int i)
{
return i; //return i为线性探测,i*i为平方法
}
int Hash_I(int key, int i)
{
return (Hash(key) + Inc(i)) % HASHSIZE; //处理冲突
}
bool Insert_Find(int* table, int key)
{
bool res = false; //假设插入失败
for (int i = 0; i < HASHSIZE; ++i)
{
int pos = Hash_I(key, i);//查找插入位置
if (table[pos] == 0) //如果插入成功res置为true,哈希表插入关键字
{
table[pos] = key;
res = true;
break;
}
}
return res;
}
void Insert_Ar(int* br, int n, int* table)
{
if (br == nullptr || n < 1 || table == nullptr) return;//判空
int i = 0;
while (i < n)
{
int tmp = rand() % 10000 + 1; // 1.. 10000
if (Insert_Find(table, tmp))//如果在哈希表中插入成功,在数组插入随机值
{
br[i] = tmp;
++i;
}
}
}
int main()
{
int ar[ARSIZE] = {}; // 1 .. 10000
int table[HASHSIZE] = {}; //
Insert_Ar(ar, ARSIZE, table);
return 0;
}
哈希函数法算是比较优秀的处理方式。上述代码的是线性探测法处理冲突。还有链地址法等等。