数组初始化为随机值并且不能重复

题目:

定义一个int型的一维数组,包含10个元素,用随机整数初始化。

生成随机数

0…9

int tmp=(int) (Math.random()*10);//[0.0,1.0)  强转  注意优先级(后面*10要带括号)
//int tmp=new Random().nextInt(10);//[0,9)

1…10

只需要在上面的基础上加个1

保证值不重复

法1:暴力查找

每生成一个新的先在已生成的里面找,有重复的,就重新生成,没有,便可赋值。
缺点是时间复杂度不好。

/*
         n是有效数字的个数(即已经生成了几个数)
         value是要查找的值
         若找到,便返回下标位置
     */
    private static  int  FindValue(int[] br,int n,int value){
        int pos=-1;
        for(int i=0;i<n;i++){
            pos=i;
            break;
        }
        return  pos;
    }
private static void Init_Ar(int[] ar) {
	 Random random = new Random();
        int tmp=0,j=0;
         //方法1
        for(int i=0;i<ar.length;i++){
            //初始化为随机值 1...10
            do{
                tmp=random.nextInt(10)+1;
            }while(FindValue(ar,i,tmp)!=-1);
            ar[i]=tmp;
        }
        //方法2
        while(j<ar.length){
            int val=random.nextInt(10)+1;
            if(FindValue(ar,j,tmp)!=-1){//若不重复
                ar[j]=val;
                ++j;//不需要赋值,直接加一,就用++i吧
            }
        }
}
       

法2:查表

表的长度为数字种类数+1,(不是默认值0,就说明已经生成过该数)若没生成该数,将对应下标的数组值置为1
缺点:当数字种类多了,表长就过于大了

int[] table=new int[11];//产生数范围为1。。。10
        while(j<ar.length){
            int val=random.nextInt(10)+1;
            if(table[val]==0){//若不重复
                ar[j]=val;
                table[val]=1;
                ++j;//不需要赋值,直接加一,就用++i吧
            }
        }

法3:HashNode(key,value)

  • 若随机产生值的范围为1…100000,此时仍然只需要10个数。由于冲突可能性比较小,不便于使用上面的方式。
  • 声明一个HashNode(key,value)类,其中key为关键码,即存放的数字,value是标志位,默认为0,表示该处没放值。
  • 再定义一个 HashNode[] table,table的长度即为需要的随机数个数
  • 此种方法用的不多,因为只能放数字,删除数字不好处理
class HashTable{
    class  HashNode{
        int key;
        int value;//标志位(默认为0,代表该处没放值)

        public HashNode(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    HashNode[] table;
    int maxsize;//个数(注意下标是0.。。maxsize-1)

    public HashTable(int n) {
        maxsize=n;//因为要生成指定数量个随机数
        table=new HashNode[maxsize];
    }

    //仅生成hash值(即存放的位置)
    public int Hash(int kx){
        return kx%maxsize;//结果为0.。。maxsize-1
    }

    public  int Inc(int i){//增量
        return  i;//线性探测
//         return  i*i;// 平方探测
    }

//    解决Hash冲突
    public int Hash_Inc(int kx,int i){
        return (Hash(kx)+Inc(i))%maxsize;
    }

    //成功则为true,有重复值或满了则false
    public boolean put(int kx){
        boolean res=false;//res即result

        for(int i=0;i<maxsize;i++){
            /*
                生成kx的hash地址,i用于处理冲突
                若没进入任何一个if(即有哈希冲突 且 没发现有该值),就啥也不干到下一轮
            */
            int pos=Hash_Inc(kx,i);
            /*
             没有哈希冲突,就 可以 放
             注意:有哈希冲突不代表值相同,只是Hash地址一样,需要找下一个哈希位置
             if和else if 最多只能进一个
             */
            if(table[pos].value==0){
                table[pos].key=kx;
                table[pos].value=1;
                res=true;
                break;
            }
             /*
               当上面不成立,才可能进到这里
               即该位置有值 且 值为kx,就不试了,返回fasle
             */
            else if(table[pos].key==kx){
                break;
            }

        }
        return res;
    }
    //有就返回下标
//    public int get(int kx){
//
//    }
}

  HashTable ht=new HashTable(13);
        while(j<ar.length) {
            int val = random.nextInt(100000) + 1;

            if (ht.put(val)) {//若不重复
                ar[j] = val;
                ++j;
            }
        }

思考
  1. 链式处理冲突怎么写
    在这里插入图片描述

  2. 链表过大怎么办?

    1. 可以将table扩容量,(新容量为素数可以分布的更均匀),然后重新插入那些值
      在这里插入图片描述
    2. 也可以利用二次哈希,链接到第一个结点后面

在这里插入图片描述

法4:HashSet

  • HashSet集合的特点:无序(存储顺序和取出顺序不一致)、唯一(不可重复
  • 由于HashSet集合存储元素是唯一的,所以当要求获取10个不能重复的随机数时,无需自主判断集合中是否包含该元素,只需将随机数添加到集合中即可
        Random r = new Random();
		HashSet<Integer> hs = new HashSet<Integer>();   //创建Integer类型的HashSet集合
		while (hs.size() < 10) {
			int num = r.nextInt(10) + 1; 
			hs.add(num);     
		}

利用HashSet判断数组有无重复值
//由于hashset实现了set接口,所以它不允许集合中有重复的值,
// 在调用add方法时,如果插入了重复值,不会插入,并且会返回false。
    public static boolean cheakRepeat(int[] array){
        HashSet<Integer> hashSet = new HashSet<Integer>();
        boolean flag=true;
        for (int i = 0; i < array.length; i++) {
            if(hashSet.add(array[i])==false){
                flag=false;
                break;
            }

        }
        return flag;
//        if (hashSet.size() == array.length){
//            return true;
//        }else {
//            return false;
//        }
    }

存字符串

若现在数组不是int型,存的是字符串。我们可以这样转化:将字母变为ASCII值 乘以每一位的权重
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值