精华内容
下载资源
问答
  • .......2,new完就直接初始化:String []a = new String[]{?,?...};3.你甚至不必new:String []a = {?,?....}同样没问题。int同样适用package insertSort;import java.util.Random;public class ...

    1,String []a = new String[length];再赋值

    a[0]=?;.......

    2,new完就直接初始化:

    String []a = new String[]{?,?...};

    3.你甚至不必new:

    String []a = {?,?....}同样没问题。

    int同样适用

    package insertSort;

    import java.util.Random;

    public class test {

    /*public static void main(String[] args) {

    // TODO Auto-generated method stub

    int []a=new int[10];

    int j=0;

    for(int i=0;i

    Random random=new Random();

    a[i]=random.nextInt(50);

    }

    for(int i=0;i

    System.out.println(a[i]);

    }

    //直接插入排序  16 8 22 4 22 12

    for(int i=2;i

    a[0]=a[i];

    for(j=i-1;a[0]

    {

    a[j+1]=a[j];

    }

    a[j+1]=a[0];

    }

    System.out.println("xin");

    for(int i=0;i

    System.out.println(a[i]);

    }

    }

    */

    }

    展开全文
  • 至此,用随机数初始化数组的操作已经全部做完,我们可以看看我们现在都写了些啥: # include # include # include using namespace std ; int main ( ) { const int N = 60 ; ...

    到目前为止,我们所学的知识已经够我们干很多事了。在继续往脑子里塞新知识前,有必要总结一下现有知识都能干哪些事。把基础巩固好再向下一个目标进发。
    本节和接下来几节会以实例的方式来综合运用前面所学的知识,以此达到灵活运用的目的。(也可以理解为实验课的意思)要注意,我也会在本节里面补充大量实际运用时会用上的知识点和常用写法。若要考高分或想把编程学明白的话,其重要性甚至大于前面的几课,请务必反复阅读。

    合格要求Level1 中位:看到类似代码知道它是在干什么,能够修改程序模板达到题目要求。
    优秀要求Level1 最上位:理解90%以上的代码,在不看资料的情况下能说出大致步骤,并能自己写出大致代码,以及拥有举一反三的能力。

    以下是本节涉及的知识点
    • 用随机数初始化数组
    • 求数组最大值最小值平均值
    • 在数组里面查找元素
    • 无重复地随机数初始化数组

    用随机数初始化数组

    我们在做部分作业题时,或者是自己写好一个小程序想要测试时,往往会遇到需要初始化测试数据的问题。虽然此时可以手动给数组统一初始化为某个值,或者是赋予一个预先设计好的值,但是这样做会让测试变得单一,结果也总是固定的。想要别的测试,就需要再修改初始化的值。
    又或是我们需要一个做出类似发牌的程序,需要把一副扑克牌(以1到54来表示,具体哪张牌对应哪个数字不重要)随机打乱随机发牌,此时也需要用到随机数来填数组。比如一个人手里拿的一副牌(假设这个人会得到18张随机发出的牌)可以用一个数组表示:{18, 7, 35, 51, 1, 16, 25, 42, 15, 8, 11, 33, 46, 53, 22, 31, 29, 49}

    上述情景下,我们都需要用到用随机数初始化数组的情况。

    有重复地初始化

    我们首先来讨论最简单的情况,也就是单纯用随机数来填数组,不考虑数字是否可能重复。
    下面我们来针对这个特定场景展开讨论:

    (佟强作业题改)对于一个60人的班级,定义一个数组存放其分数。这60个人的分数由随机数生成,60人的得分相互独立,均是服从在60到100之间均匀分布随机整数。生成每个人的分数后,我们需要把全班的平均分算出来。最后输出平均分最高分最低分

    这是佟强作业题的简化版(原版比这个复杂好几倍),也是考试中程序大题里面的最基础的题。

    我们不要被各种花里胡哨的要求吓住,试着把题目分解成好几步来做:

    1. 定义一个有60个元素的int数组
    2. 把这60个元素用60到100的随机整数填充
    3. 求这60个人分数的和,在循环的时候顺便找到最高分和最低分
    4. 把算出的和除以60得到平均分
    5. 按题目要求进行输出

    有了这个基本思路以后,我们只需要把每一步都依次做出来就好。(虽然实际做的顺序可能和上述的不完全一样)

    随机数的模板

    首先,既然涉及到随机数,所以我们就要用上随机数的模板:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    int main(){
        srand(time(0));
    }
    

    始终记得随机数种子初始化一次就好。

    定义数组

    然后我们定义数组。我们可以直接定义一个含有60个元素的数组,但是由于一个班的同学可能会变(主要是题目上可能会变),如果变了的话,之后好些代码都要改,很不方便。所以我们把学生人数定义为一个常量。然后在此基础上定义数组。

    const int N = 60;
    int score[N];
    

    这样,一旦今后需要修改学生人数,只需要把代码里面N的值修改就可以了。

    用上随机数

    下面我们开始用上随机数。首先回忆我们如何需要生成一个60到100之间分布的随机整数。rand()会为我们返回一个0到很大的数的整数,我们通过求余的方式可以获得一个更窄范围的随机数。比如rand()%41会为我们返回0到40之间的随机整数。我们在rand()%41的基础上加60,就能得到60到100之间的随机整数。
    也就是说,我们对数组元素的初始化的基本语句是:

    score[0] = rand()%41+60;
    

    然后针对数组的每个元素都要执行一遍随机数操作,所以我们用上for循环:

    for(int i=0; i<N; i++)
        score[i] = rand()%41+60;
    

    注意for里面是小于符号而不是小于等于。

    回顾一下

    至此,用随机数初始化数组的操作已经全部做完,我们可以看看我们现在都写了些啥:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    int main(){
        const int N = 60;
        int score[N];
        
        srand(time(0));
        for(int i=0; i<N; i++)
            score[i] = rand()%41+60;
    }
    

    加上输出

    当然由于没有任何输出语句,所以这个程序运行起来是没有任何输出的。我们可以在for里面加上cout语句,把每个数组元素都输出,这样我们就能看到随机数都怎么初始化我们的数组了。
    参见附件知识网络1.1.1(OneNote笔记本上),试运行看看效果。

    求和

    接下来我们试着对这60人的分数进行求和和找最大值最小值的操作。
    求和的话,我们需要另外定义一个变量来存储其和。

    int sum=0;
    

    一定要记得把sum初始化为0。
    然后在for循环内逐一累加即可:

    for(int i=0; i<N; i++)
        sum+=score[i];
    

    找最大值和最小值

    最大值和最小值的找法是相似的。大概原理就是,如果目前这个元素比已知的最大值还要大,那么就把最大值更新为这个元素。在最开始时我们拿到的数组第一个元素就是最大值和最小值的初始值(因为此时我们还没开始循环,只能先拿数组的第一个值来初始化)。

    如果我们用0来初始化最小值的话,因为后面的分数总是大于60,所以这个最小值永远都是0,也就不会更新了。最大值也是一个道理。所以我们直接用数组的第一个元素来初始化。这样哪怕最大值或最小值一直没有被更新,那么它也是数组中的一个元素。(逻辑有点绞,看不明白的话请及时提问)

    所以我们大概有如下代码:

    int max=score[0], min=score[0];
    for(int i=0; i<N; i++){
        if(score[i]>max) max=score[i];
        if(score[i]<min) min=score[i];
    }
    

    这里在for第一次循环时会重复比较第一个元素,可以跳过。但为了后面方便没有改。

    合并for循环

    注意到我们这个求最大值和最小值的操作用到的for循环和求和用的for循环是同一个,它们互相也不干扰,所以我们可以合并。合并之后就是下面的样子:

    int sum=0;
    int max=score[0], min=score[0];
    for(int i=0; i<N; i++){
        sum+=score[i];
        if(score[i]>max) max=score[i];
        if(score[i]<min) min=score[i];
    }
    

    计算平均数

    平均数的计算就很简单了。不过要注意sumN都是整数,在进行除法前要先把其中一个转换为小数。

    double ave=sum/(double)N;
    

    最后是输出

    按照自己喜欢的格式输出就可以了。

    cout<<"The average is "<<ave<<endl;
    cout<<"Max score is "<<max<<endl;
    cout<<"Min score is "<<min<<endl;
    

    小结

    我们整理一下,现在我们写了些什么:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    int main(){
        //定义学生人数和数组 
        const int N = 60;
        int score[60];
        
        //初始化分数 
        srand(time(0));
        for(int i=0; i<N; i++)
            score[i] = rand()%41+60;
            
        //求最大值最小值以及元素和 
        int sum=0;
        int max=score[0],min=score[0];
        for(int i=0; i<N; i++){
            sum+=score[i];
            if(score[i]>max) max=score[i];
            if(score[i]<min) min=score[i];
        }
        
        //求平均值 
        double ave=sum/(double)N;
        
        //输出 
        cout<<"The average is "<<ave<<endl;
        cout<<"Max score is "<<max<<endl;
        cout<<"Min score is "<<min<<endl;
    }
    

    参见附件知识网络1.1.2(在OneNote笔记本里面),试运行看看效果。
    由于引入了随机数,所以每次打开这个结果都会不太一样。

    无重复的初始化

    接下来的情况会复杂一些,不过也没有那么麻烦。这种情况考试目前还没有考过,如果前面的部分看着都吃力的话,就别往下看了。
    如同本节开头时举的例子一样,我们可能会编程来模拟发牌。但是牌每张都是独一无二的,单纯随机数可能会发生发到重复的牌的情况。所以此时我们需要做特殊处理来保证发牌没有重复的牌。

    我们还是以下面的情景开始讨论:

    (佟强作业题改)我们把一副扑克牌的每张牌进行编号,以红桃、方片、梅花、黑桃的顺序,123456789 10 JQK的顺序为每张牌编号,比如红桃A为1,红桃K为13,方片A为14,梅花A为27等等。小王为53,大王为54。
    我们要为其中一个玩家随机发18张牌。每张牌用其对应的编号存储。(其实还要为另外两个玩家发牌,不过就会太麻烦,并且没有什么新知识点,所以略去)

    类似的例子在我接触过的范围内还没有考过。所以如果单纯应试的话,真的可以不用看了。如果希望提升自己的编程能力的话可以看。

    解决这个问题我们可以有很多种办法,下面将会详细讲解三种比较基础的解法:(这些名词是我自己取的,并没有统一的说法)

    • 返回查找
    • 登记排除
    • 排序

    返回查找

    返回查找,即每生成一个新的随机数,就返回去查找此前是否已经生成过相同的随机数。如果已经有了,那么就重新生成一个随机数,直到这个新随机数此前没有出现过,此时再把这个随机数填入数组中。(听起来就很麻烦)
    因为每次填入的数都是新的数,所以自然数组不会有重复元素。
    我们根据这个思路,可以把情景分解为如下的步骤:

    1. 初始化随机数种子
    2. 生成一个随机数
    3. 查找数组里面是否存在这个数,如果存在,则返回第2步,否则继续向下执行
    4. 把这个数填进数组
    5. 如果数组还没有被填满,则返回第2步

    基本框架

    前面的两步都还算简单。我们先把基本的框架写出来,这个版本的代码,发牌可能有重复:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    int main(){
        const int N = 18; 
        int cards[N];
        
        srand(time(0));
        for(int i=0; i<N; i++){
            int r=rand()%54+1;
            cards[i]=r;
        }
    }
    

    查找数组元素

    第3步中,查找数组中的元素是新的操作。查找我们也是逐一查找。对于数组内的每个元素,看它是否是我们要找的那个元素,如果找到了就提前终止循环,如果没找到就接着比较下一个元素。
    在上述的例子里面,我们在cards数组的下标为0i-1的元素里面查找新生成的那个随机数。
    查找可以用这个代码:

    bool found=false;
    for(int j=0; j<i; j++){
        if(cards[j]==r){
            found = true;
            break;
        }
    }
    

    我们用了一个新的for循环,对从数组下标0i-1的元素进行遍历。如果这个元素的值与我们生成的随机数相同,就把标记found改为true。这样,当循环结束时,如果foundtrue,就说明这个随机数出现过了。否则就说明这个随机数是新的。

    生成一个之前没出现过的随机数

    完成了查找元素后,我们要实现第三步的其余逻辑(其实这个逻辑里面隐含了一个循环):
    大概结构应该是这样的:生成随机数-查找-比较-生成随机数-查找-比较-……
    我们注意到“比较”这一步是在循环的最后,所以用do-while循环会最方便。
    我们可以这么写:

    do{
        生成随机数;
        看这个随机数是否在数组内; 
    }while(这个随机数在数组内);
    

    写成代码是这样子的

    把文字语言替换成之前写出的代码,就是下面这个样子:

    int r;
    bool found;
    do{
        r=rand()%54+1;
        found=false;
        for(int j=0; j<i; j++){
            if(cards[j]==r){
                found = true;
                break;
            }
        }
    }while(found);
    

    这样,当这串代码执行完毕后,变量r里面存的随机数,就一定是cards数组目前还没有的,一个新的数字。

    把这个随机数填到数组里面

    剩下的工作就很简单了,把这个新的数字存到数组里面,并开始填下一个数字。

    cards[i]=r; 
    

    最后的输出

    此时我们就填完了。最后可以输出一下看看效果:

    for(int i=0; i<N; i++){
        cout<<cards[i]<<" ";
    } 
    

    小结

    整理一下,现在我们写了什么:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    int main(){
        //定义数组 
        const int N = 18; 
        int cards[N];
        
        //初始化随机数种子 
        srand(time(0));
        
        //对于数组内的每个元素 
        for(int i=0; i<N; i++){
            int r;
            bool found;
            do{
                //生成一个随机数 
                r=rand()%54+1;
                found=false;
                //查找这个随机数是否已经出现过了 
                for(int j=0; j<i; j++){
                    if(cards[j]==r){
                        found=true;
                        break;
                    }
                }
            //只要出现过了,就重新生成随机数 
            }while(found);
            //若没出现过,就把这个随机数填入数组 
            cards[i]=r; 
        }
        
        //输出数组 
        for(int i=0; i<N; i++){
            cout<<cards[i]<<" ";
        } 
    }
    

    参见知识网络1.1.3,试运行看看效果。

    可以发现的确是没有重复了。这里我们用到了三重循环,逻辑比较复杂,但拆分来看其实都还算简单。如果我直接把整个代码抛过来的话估计多半的同学都会直接被吓跑吧。

    登记排除

    登记排除,就是仿照真正发牌时的状态,发过的牌就是没有了,不可能再被发一次。也就是说,只要这张牌被发出,则发牌员手里就再也没有这张牌了。虽然说思路不太一样,但其原理和返回查找是相似的。在这种情况下,我们要为每张牌进行登记处理,如果未发出,则它就可以被发出,如果已发出,它就不能再被发出。虽然是个很傻的逻辑,但这就是登记排除解法的最基础的思路。
    在这种思路下,情景可以被分解为如下步骤:

    1. 初始化随机数
    2. 定义一个数组来标记每张牌的状态
    3. 定义一个数组来存放发出去的牌
    4. 生成一个随机数
    5. 查找数组内登记的这张牌的状态
    6. 如果这个随机数对应的牌已发出,则回到第4步。否则就继续向下执行
    7. 把这个随机数添加到发出去牌的数组里面。并且将这张牌的状态登记为“已发出”
    8. 只要玩家持有的牌的数组还没填满,就返回第4步

    定义状态数组

    首先,我们需要定义一个数组来标记每张牌的状态。为了方便查阅,我们一般用数组的元素下标来表示牌号,元素的内容表示这张牌的状态。比如我们可以定义一个有54个bool元素的数组。当第一个元素存放的是true时,即表示第一张牌(红桃A)已经被发出去了。而当第14个元素存放的是false时,即表示第14张牌(方片A)还没有被发出去。通过这样一个数组,我们就可以准确地记录每张牌的状态,而不需要再慢慢查找是否发过这张牌。
    其定义可以是这样的:

    bool status[54];
    

    我们需要对这个数组进行初始化,将每个元素都初始化为false,以表示每张牌都还没发出去。用大括号的方式的话我们得写54个false,简便起见,我们使用for循环。

    for(int i=0; i<54; i++)
        status[i]=false;
    

    需要注意的是,由于数组下标是从0开始的,而我们牌号却是从1开始的,所以第i张牌对应的数组下标应该是i-1。这样子,判断第i张牌是否发出去的表达式就简便到仅剩下status[i-1]了。

    生成随机数

    于是接下来,我们生成随机数:

    int r;
    r=rand()%54+1;
    

    只要这个随机数对应的牌发出去了,那么就重新生成一个随机数:

    do{
        r=rand()%54+1;
    }while(status[r-1]);
    

    可以发现,在这个思路下的代码,要比前面一种的简单太多。这主要是因为我们引入了一个新的数组,多占用了内存空间,所以代码量也得到了一定优化。

    把牌发出去

    剩下的就和前一个思路类似了。当获取到了一张还未发出去的牌时,把这张牌发出去(加入玩家持有的牌的数组里面),并且把这张牌标记为已发出。

    cards[i]=r;
    status[r-1]=true; 
    

    最后一步

    然后是对数组的每个元素都执行发牌过程,用for表示,这和前一个思路是一样的。最后是输出:

    for(int i=0; i<N; i++){
        cout<<cards[i]<<" ";
    }
    

    小结

    整理一下,现在我们写了什么:

    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    int main(){
        //定义常量和数组 
        const int N = 18; 
        bool status[54];//记录每张牌的状态 
        int cards[N];//玩家手上拿到的牌 
        
        //初始化状态数组 
        for(int i=0; i<54; i++)
            status[i]=false;
            
        //初始化随机数 
        srand(time(0));
        
        //接下来是发牌 
        for(int i=0; i<N; i++){
            int r;
            do{
                //随机获取一张牌 
                r=rand()%54+1;
            //如果这张牌已经发出,则重新取牌 
            }while(status[r-1]);
            //若未发出,则将牌发出,并将牌状态标记为已发出 
            cards[i]=r;
            status[r-1]=true; 
        }
        
        //打印发牌结果 
        for(int i=0; i<N; i++){
            cout<<cards[i]<<" ";
        }
    }
    

    参见“知识网络1.1.4”,试运行看看效果。

    排序

    这种方法涉及到后面会学习的数组排序问题,在后面学习了结构体或者对象之后,这种方法才具有现实意义。所以我并不在这里细讲。
    但是其基本思路和原理还是值得一提的。

    排序法就更加接近真实的发牌状态。我们发牌时,一般都会把牌先洗好(打乱),然后再从上至下拿出18张牌,就已经是随机发放的了。

    在排序法下,我们先利用随机数,将存有1到54数字的数组元素内部顺序打乱,然后直接输出这个数组的前18个元素,便能做到无重复发牌的效果。

    但是具体如何打乱其实还比较麻烦。一般我们是将每张牌与一个随机数绑定,然后将随机数按大小顺序排序。由于每张牌获得的随机数大小关系是不确定的,那么排序后每张牌的顺序也就自然打乱了。

    虽然说起来还算简单,但是由目前的知识来做,虽然可以做到,但会特别麻烦。所以在此不讲了(这一节也已经太多内容了)。

    展开全文
  • 使用指定范围随机数初始化数组

    千次阅读 2017-02-27 20:29:27
    static void randomInitArray(int[] array, int min, int max){ for(int i = 0;i Random r = new Random(); while(true){ int n = r.nextInt(max)+1; if(n >= min && n array[i] = n; break;...}

    一、

    static void randomInitArray(int[] array, int min, int max){

    for(int i = 0;i < array.length;i++){
    Random r = new Random();
    while(true){
    int n = r.nextInt(max)+1;
    if(n >= min && n <= max){
    array[i] = n;
    break;
    }
    }
    }

    }

    二、

    static void randomInitArray(int[] array, int min, int max){

    Random r = new Random();

    for(int i = 0;i < array.length;i++){
    array[i] = r.nextInt(max - min + 1) + min;
    }
    }
    }

    }


    展开全文
  • #include #include #include//时间头文件 int main() { time_t ts;//设置时间变量 unsigned int randdata = time(&ts);//获取时间,转换为无符号int ... //用随机数初始化数组 for(int i=0;i;i++) {
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>//时间头文件 
    int main()
    {
    	time_t ts;//设置时间变量 
    	unsigned int randdata = time(&ts);//获取时间,转换为无符号int 
    	srand(randdata);//设置随机数种子
    	int a[10];
    	//用随机数初始化数组
    	for(int i=0;i<10;i++)
    	{
    		a[i] = rand()%100;//0--99
    		printf("%d,%x\n",a[i],&a[i]);
    	} 
    	printf("-----------------------------------------------------\n");
    	//下面的代码块是求最大值 
    	{
    		int max;//最大值下标
    		max = 0;//假设a[0]最大
    		//求最大值
    		for(int i=1;i<10;i++)
    		{
    			printf("%d,%d,%d,%d\n",i,max,a[i],a[max]);
    			if(a[i]>a[max])
    			{
    				max = i;
    			}
    		} 
    		printf("最大值a[max]=%d\n",a[max]);
    	}
    	//下面的代码块是选择排序
    	{
    		for(int i=0;i<9;i++)
    		{
    			int min = i;//假设是当前最小值的下标 
    			for(int j=i+1;j<10;j++)
    			{
    				if(a[j]<a[min])
    				{
    					min = j;
    				}
    			}
    			if(min!=i)//下标相同表明下标没有交换,就无需交换数据 
    			{
    				int temp = a[min];//temp保存最小值
    				a[min] = a[i];
    				a[i] = temp;//数据交换 
    			}
    		}
    		printf("第一种选择排序后数组的结果如下:\n"); 
    		for(int i=0;i<10;i++)
    		{
    			printf("%d\t",a[i]);
    		} 
    	} 
    	{
    		for(int i=0;i<9;i++)
    		{
    			for(int j=i+1;j<10;j++)
    			{
    				if(a[i]>a[j])
    				{
    					int temp = a[i];
    					a[i] = a[j];
    					a[j] = temp;
    				}
    			}
    		}
    		printf("第二种选择排序后数组的结果如下:\n"); 
    		for(int i=0;i<10;i++)
    		{
    			printf("%d\t",a[i]);
    		} 
    	}
    	{
    		int min,temp;
    		for(int i=0;i<9;i++)
    		{
    			min = i;
    			for(int j=i+1;j<10;j++)
    			{
    				if(a[j]<a[min])
    				{
    					min = j;
    				}
    			}
    			temp = a[min];
    			a[min] = a[i];
    			a[i] = temp;
    		}
    		printf("第三种选择排序后数组的结果如下:\n"); 
    		for(int i=0;i<10;i++)
    		{
    			printf("%d\t",a[i]);
    		} 
    	} 
    	return 0;
    } 

    展开全文
  • 如下代码,我通过new运算符建立了一个动态数组,然后进行初始化初始化时,我是通过rand()方法和srand()方法进行随机数初始化的,这两个方法是C++的标准(stdib.h)提供用于产生随机数的函数,其中rand()方法是返回...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 532
精华内容 212
关键字:

初始化数组随机数