在14号我们学习了数组的进阶,虽然数组这个概念理解起来很容易:
数组
用来批量存储某一类数据的变量。一个存储空间四个字节.
定义数组之前要定义类型与数组大小(元素的个数)。
这是需要注意的一些知识点,数组的下标是以0开始计,定义的长度不能出现在下标内,不然会报错,(一开始没有少犯这个毛病)。
然后就是数组的应用,虽然单看理论好像就一点点,不过真正应用起来就不是一点点这么简单了,现在我们接触的只是单个数组,最后一道进阶题目里面会稍微进阶一点,尽请期待。
下面是数组的一个很简单的例子:
int[] arr = new int[10];//定义一个数组,名称是arr,长度为10,条件齐全,life is good~说道这句生活真美好,最近我在看斯坦福开放课程的编程方法学,里面老湿的口头禅就是这句~感觉还可以,在网易公开课就可以搜到,有兴趣的可以去看一下,网易公开课里面有不少好资源,偶尔去淘一下可能会有小收获哦~妹的一个注释这么长……
for(int i =1;i<=arr.length;i++)//这个地方有一个需要注意的地方,因为在数组里面下标是以0开始计的,所以在下面的i都需要-1,不然就会超过索引界限,当然可以把i的初始值设置为0,但是中间循环条件的等号就要去掉,不然同样会报错。所以养成好习惯 ,把初始值设为1,不要忘了在循环里面-1~
{
arr[i-1]=i;//这句非常简单了吧,将arr的下标0~6的变量赋予1~7的值
console.writeline(arr[i-1]);
}
这是数列的非常基本的小小应用,或者说没有啥应用的地方,不过这样就说错了,类似于这段代码的语句在下面会非常常见的,你得爱上他才行。
下面来真正看一个应用的题目:做一个小程序,一次输入第1到第10名球员的分数,找出最高分与最低分,算出总分与平均分,而且在结果里面要显示最高分与最低分的球员号码,如果得分为零则表示该队员没有上场,且不计入平均分。
下面来分析一下这道题,一共需要输出四个数字,最高分,最低分,平均分,总分,然后还要在找出最高最低分的同时找到队员的号码,首先创建一个数组,用来存储队员的得分,让用户输入数值并保存起来,最高最低分就是将数值一个个相比较,然后找出最大或者的放在一个变量中,找出的同时用另一个变量记录一下队员的号码,总分的话用一个迭代就能搞定,至于得分为零的,用一个if判断一下,然后用另一个变量记录一下得分为零的球员数,在计算平均分的时候减去这些人数就可以了。这就是大体的思路,代码如下:
int[] score = new int[10];//创建一个数组,用来存储球员的分数。
for(int i =1;i<=score.length;i++)//length是score的长度,这样写的话如果改动score的长度也不用再下来更改代码。
{
console.writeline("请输入第{0}个球员的分数:",i);//因为i的初始值为1,所以不用更改i的值,方便我们的理解,但是在下面赋值的时候一定记得-1、
arr[i-1]=convert.toint32(console.readline());//这个地方记得-1 因为下标是以0开始计。
}
//接下来我们要比较每两个数组之间的大小。
int max =0;
int min = 10000;//为什么将min设置这么大呢,是因为当有比min小的数字时,min就将被替换,如果min的值设置太小可能结果就会不淡定了。
int maxNo = 0;
int minNo = 0;//这两个数字用来存储最高,最低分球员的号码。
int count =0;//用来计算得分为0的球员
for(int i =1;i<=score.length;i++)
{
if(score[i-1]==0)
{
count++;//将未上场球员的人数加1
continue;//一旦出现球员分数等于零的情况,马上进行下次循环,直到不是0为止,
}
if(score[i-1]>max)
{
max = score[i-1];//一旦有比max大的就将这个值扔到max中。(好血腥……)
maxNo = i;//记录下当前最大值的下标
}
if(score[i-1]<min)
{
min = score[i-1];//一旦有比min大的就将这个值扔到min中。(又见血腥……)
minNo = i;//记录下当前最小值的下标,记住,第几名球员的话就不用去-1了,不然会有误差
}
}
console.writeline("最高分是第{0}名球员的{1}分,最低分是第{2}名球员的{3}分,其中{4}名球员没有上场,不计入最低分。",maxNo,max,minNo,min,count);//这个不用解释了吧……前面都说的很清楚了
int sum = 0;//用来计算分数的和。
double avg;//先定义一个浮点型的平均数,因为可能会有小数。
for(int i =1;i<=score.length;i++)
{
sum += score[i-1];
}
avg = sum*1.0/(score.length-count);
console.writeline("总分是{0},平均分是{1}",sum,avg.tostring("#.00"));//稍微设置一下格式,以免无法是无限循环小数、
这道题应该是数组的进阶题,多次用到了for循环,提取数字,比较数字,包括迭代都有所涉及,应该注意的地方还是下标减一的问题,其他的有了思路都可以写出来。
下面我们来讲一下冒泡排序
乍一听挺可爱的名字,结果写起来一点也不可爱。这是我对冒泡的印象,不过老湿解释了一下冒泡的原理,并且做出了一个表格,让我们一目了然
9 | 9 | 9 | 9 | 9 | 3 | 3 | 3 | 3 | 3 | 3 |
|
28 | 28 | 3 | 3 | 3 | 9 | 9 | 9 | 9 | 9 | 9 |
|
3 | 3 | 28 | 28 | 28 | 28 | 28 | 17 | 17 | 17 | 17 |
|
50 | 50 | 50 | 50 | 17 | 17 | 17 | 28 | 28 | 28 | 28 |
|
17 | 17 | 17 | 17 | 50 | 50 | 50 | 50 | 50 | 50 | 50 |
|
每两个数字比较叫做循环一次,(内层for)
趟数n-1 每趟的次数:n-趟数
每次两两循环,每次把最大的数字放在最下面,然后依次循环,直到排列完毕。
下面来个例子,设置一个长度为5的数列,然后用冒泡排序
int[] arr = new int[5]{32,54,62,17,43};//这是设置数列里面比较便捷的办法,但是如果数列长度太高了就算了,到时候数半天。。
for(int i =i;i<=arr.length-1;i++)
{
for(int j =1;j<=arr.length-i;j++)
{
if(arr[j]<arr[j-1])
{
int temp = arr[j-1];
arr[ j-1]=arr[j];
arr[j]=temp;//这三句表示了将比较大的一个数列中的数arr[j]放到最底层,如此循环,直到五个数字都排列完毕为止
}
}
}
其实冒泡排序相对来说比较好理解,难点在于两个循环的理解上。下面我们讲一下二分法,二分法用于查找数列中有没有目标值,而且可以减少一半的查找量。
二分法的思路是,设我们需要查找的数字为x,要去查找数列arr中有没有包含x,首先将x用冒泡法自上而下排列好,然后用x的中间一个数去跟x比较,如果x大,说明x可能在数列的更下面(更大的数字里面),反之,如果x小于中间值,则说明x可能在数列的上面部分。这就是二分法的思路。
下面是代码,依然用一个比较简单的数列。如果你愿意,可以设置一个长度为100的数列。。
int[] arr = new int[10]{12,35,75,42,16,78,32,55,89,63};
for(int i =1;i<=arr.length-1;i++)
{
for(int j =1;j<=arr.length-i;j++)
{
if(arr[j-1]>arr[j])
{
int temp = arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}
}
}
//冒泡排序 不解释。
int max = arr.length;
int min = 0;
int mid =(max+mid)/2;//取出中间值
console.writeline("请输入你想查找的数字:");
int goal= convert.toint32(console.readline());
while (goal != arr[mid] && max > min)
{
if (arr[ mid] <goal)
{
min = mid+1;
}
if ( arr[mid]> goal)
{
max = mid-1;
}
mid = (min + max) / 2;
}
if (goal != arr[mid])
{
Console.WriteLine("您输入的数字不存在……");
}
else
{
Console.WriteLine("{0}在数列的位置{1}上", goal, mid+1);
}
这道题挺难以理解的,但是仔细看过以后也没有想象中复杂,如果输入的值比中间值还要大,就要将下限提高,以取得更高的mid值,反之亦然。