基于上次我们认识到了如何学习数组,同时也掌握了数组的一些基础用法与算法;接下来我们更深入一步,那我们如何使数组进行反转呢?
反转数组,就指的是将数组里面存储的元素倒过来逆序输出。
比如原来的数组为:1,2,3,4;
那么反转后的就是:4,3,2,1。
接下来我们给出思路:
这种思路就是将上图中的相关对称位置的元素相互交换、最后直接遍历数组输出;那么我们现在要考虑的就是需要遍历多少次?
这个不能说每次数组长度不一样,我给他每一次都赋值赋一次,我们可以用长度直接除以二就是需要交换的次数。
以下给出代码:
int[] arr = {1, 2, 3, 4, 5};
System.out.println("数组翻转之前为:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
System.out.println("数组翻转之后为:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
其结果为:
数组翻转之前为:
1 2 3 4 5
数组翻转之后为:
5 4 3 2 1
这种思路就是给数组左右各加一个标识符,分别指向首个元素和最后一个元素;在遍历的时候,左标识符与右标识符一起移动进行遍历。
具体代码如下:
int[] arr = {1, 2, 3, 4, 5};
System.out.println("数组翻转之前为:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
for (int left = 0, right = arr.length - 1; left < right; left++, right--) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
System.out.println("数组翻转之后为:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
结果为:
数组翻转之前为:
1 2 3 4 5
数组翻转之后为:
5 4 3 2 1
当我们给定的一个数组难以存放或需要减少存放内存时,我们可以对数组进行扩容与缩容的操作让数组能够实现我蒙的需求。
数组的扩容就是指给定一个随机类型的数组,以int类型为例,实现数组的扩容,要求新增加的元素默认放在数组的末尾。
题目要求:
现有数组 int[] arr = new int[]{1,2,3,4,5}; ,现将数组长度扩容,并将17,25,38三个数据添加到arr数组中,如何操作?
题目分析:
我们想要对其数组进行扩容,就需要在原有的数组的基础上再添加一个新的空数组来存放我需要添加的数组元素;最后将它赋给原来的数组输出即可。
以 int[] oldArr = new int[]{1, 2, 3, 4, 5};数组为例,我们对他扩容三个单位来存放新的数据元素,步骤就为:
int[] oldArr = new int[]{1, 2, 3, 4, 5};
System.out.println("扩容前的数组为:");
for (int i = 0; i < oldArr.length; i++) {
System.out.print(oldArr[i] + "\t");
}
System.out.println();
int[] newArr = new int[oldArr.length + 3];
for (int i = 0; i < oldArr.length; i++) {
newArr[i] = oldArr[i];
}
newArr[oldArr.length] = 17;
newArr[oldArr.length + 1] = 25;
newArr[oldArr.length + 2] = 38;
oldArr = newArr;
System.out.println("扩容后的数组为:");
for (int i = 0; i < oldArr.length; i++) {
System.out.print(oldArr[i] + "\t");
}
System.out.println();
结果为:
扩容前的数组为:
1 2 3 4 5
扩容后的数组为:
1 2 3 4 5 17 25 38
数组的缩容就是指 以int型数组为例,将原来的数组其中的几个元素减去,且在数组长度大于1的情况下输出新数组。
题目要求:
现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。
题目分析:
我们对其删除数组中的元素,有两种办法;
其一就是增加爱一个符合长度的新数组,将原数组赋给新数组输出即可。
其二就是将想要删去部分的元素用循环赋给第一个,再将循环结束后最后一个值赋值为零输出数组;
对于这个要求我们可以采用第二种方法较为高效。
其代码为:
int[] oldArr = new int[]{1, 2, 3, 4, 5, 6, 7};
System.out.println("缩容前的数组为:");
for (int i = 0; i < oldArr.length; i++) {
System.out.print(oldArr[i] + " ");
}
System.out.println();
int delIndex = 4;
for (int i = delIndex; i < oldArr.length - 1; i++) {
oldArr[i] = oldArr[i + 1];
}
oldArr[oldArr.length - 1] = 0;
System.out.println("缩容后的数组为:");
for (int i = 0; i < oldArr.length - 1; i++) {
System.out.print(oldArr[i] + " ");
}
System.out.println();
结果为:
缩容前的数组为:
1 2 3 4 5 6 7
缩容后的数组为:
1 2 3 4 6 7
我们在使用数组时,通常会需要查找某一个数组中的元素、元素位置、元素下标等等...那么我们如何去查找呢?
这里介绍两种查找方式:顺序查找和二分查找。
顺序查找 又称 线性查找 ,对于顺序表,可通过数组下标递增来扫描每个元素,村儿查找到我们需要的值。
题目要求:
我们就以顺序查找这个数组为例:int[] arr = {4,5,6,1,9};
题目分析:
采用顺序查找,就是从数组的第一个元素,一直查找到数组的最后一个元素,若找到所需元素退出循环输出;
那么我们就先需要对其进行排序,再从中查找数值输出即可。
具体代码如下:
int[] arr={1,3,5,8,9,5,2,5,8,26};
int index=-1;
int value=26;
for (int i = 0; i < arr.length ; i++) {
if(arr[i]==value){
index=i;
break;
}
}
System.out.println("查找的数据为:"+value+"\n索引为:"+index);
结果为:
查找的数据为:26
索引为:9
二分查找,也称为折半查找,是一种在有序数组中查找特定元素的搜索算法。 它的基本思想是将数组分成两半,比较中间元素与目标值,根据比较结果决定下一步查找哪一半,直到找到目标元素或确定元素不存在。 二分查找的时间复杂度为O (log n),在有序数组中具有较高的搜索效率。
题目要求:
我们以这个数组为例:int[] arr={1,3,26,54,43,76,32,28};
题目分析:
对于二分查找,我们首先就要定义三个标识,一个从左向右移动,一个从右向左移动,一个指向中间值;同时向内移动进行查找。当mid>检索值时,我们需要将end改为mid-1;而当mid<检索值时,将head改为mid+1,检测即可。
代码如下:
主方法:
int[] arr={1,3,26,54,43,76,32,28};
System.out.println(erfen(arr,54));
方法内:
int head = 0;
int end = arr.length - 1;
while (true) {
if (head > end) {
return -1;
}
int mide = (head + end) / 2;
if (arr[mide] < value) {
head = mide + 1;
} else if (arr[mide] > value) {
end = mide - 1;
}else
{
return mide;
}
}
结果为:
3
排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。 分 内部排序 和 外部排序,若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。
我们所熟知的数组,在日常的编写代码运行程序时,也同样用到排序,那么排序有几种方法呢?
现有的排序种类就分为(四大类):
下面我们今天用到较为常用的冒泡排序、快速排序和插入排序。
所谓的快速排序,就是先选取一个标准元素,将数组分为两部分,比标准元素小的放左边,比标准元素大的放右边。
一轮的排序下来,这个标准元素一定在最终排序的正确位置上。
具体代码为:
主方法:
int[] arr = {7, 10, 2, 4, 7, 1, 8, 5, 19};
kuaisupaixu(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
方法内:
int i, j, temp, t;
if (low > high) {
return;
}
i = low;
j = high;
temp = arr[low];
while (i < j) {
while (temp <= arr[j] && i < j) {
j--;
}
while (temp >= arr[i] && i < j) {
i++;
}
if (i < j) {
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
arr[low] = arr[i];
arr[i] = temp;
kuaisupaixu(arr, low, j - 1);
kuaisupaixu(arr, j + 1, high);
}
结果为:
1 2 4 5 7 7 8 10 19
冒泡排序重复地遍历要排序的数组元素,一次比较两个元素,如果他们的顺序错误(a>b)就把他们交换过来。重复地进行直到没有再需要交换,也就是说该数组已经排序完成。
这个是我们在排序时用的最多的排序方式,不做过多介绍,直接代码:
int[] arr = {12, 34, 56, 78, 89, 99, 2, 9};
//第一轮
for (int i = 0; i < 7; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第一轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
//第二轮
for (int i = 0; i < 6; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第二轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
//第三轮
for (int i = 0; i < 5; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第三轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
//第四轮
for (int i = 0; i < 4; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第四轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
//第五轮
for (int i = 0; i < 3; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第五轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
//第六轮
for (int i = 0; i < 2; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第六轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
//第七轮
for (int i = 0; i < 1; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.println("\n第七轮冒泡排序为:");
for (int i = 0; i < 7; i++) {
System.out.print(arr[i] + " ");
}
结果为:
第一轮冒泡排序为:
12 34 56 78 89 2 9
第二轮冒泡排序为:
12 34 56 78 2 9 89
第三轮冒泡排序为:
12 34 56 2 9 78 89
第四轮冒泡排序为:
12 34 2 9 56 78 89
第五轮冒泡排序为:
12 2 9 34 56 78 89
第六轮冒泡排序为:
2 9 12 34 56 78 89
第七轮冒泡排序为:
2 9 12 34 56 78 89
如果嫌弃输入的代码量太大,我们可以对它嵌套两层的for循环来进行遍历输出,即:
int[] arr={12,34,56,78,89,99,2,9};
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
System.out.println("\n第"+(i+1)+"轮冒泡排序为:");
for (int j = 0; j < arr.length ; j++) {
System.out.print(arr[j]+" ");
}
}
同样结果为:
第1轮冒泡排序为:
12 34 56 78 89 2 9 99
第2轮冒泡排序为:
12 34 56 78 2 9 89 99
第3轮冒泡排序为:
12 34 56 2 9 78 89 99
第4轮冒泡排序为:
12 34 2 9 56 78 89 99
第5轮冒泡排序为:
12 2 9 34 56 78 89 99
第6轮冒泡排序为:
2 9 12 34 56 78 89 99
第7轮冒泡排序为:
2 9 12 34 56 78 89 99
由此可见在编写代码量较大的程序时,我们可以多使用嵌套结构。
插入排序将数组数据分成已排序区间和未排序区间(有序区间和无序区间)。
我们就好比拿 4 1 3 8 7举例;
开始时有序区间就只有4,无序区间有1 3 8 7;
将无序区间的1插入到有序区间,再与4比较大小,4>1,我们将4 和1换位置,此时有序区间变为1 4,无序区间变为3 8 7;我们只需重复上述的方法,最总就能得到完整的有序排列数组1 3 4 7 8.
知道了原理,其代码为:
主方法:
int[] arr={1,54,23,12,6,78,98,66};
charu(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
方法内:
for (int i = 0; i < arr.length; i++) {
int number=arr[i];
int j=i-1;
while(j>=0&&arr[j]>number){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=number;
}
结果为:
1 6 12 23 54 66 78 98
题目要求:
随机产生10个[1,100]之间的偶数存储到数组中,并按照从小到大排序输出。
题目分析:
“随机产生”,我们就可以用Math.random来产生随机数,但要注意产生的随机数都为小数,我们需要将它强制转化为整型再乘以一百输出。之后就是采用一种排序方式对他进行排序输出即可。
代码如下:
int[] arr = new int[10];
for (int i = 0; i < arr.length ; i++) {
arr[i]=(int)(Math.random()*50+1)*2;
}
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
结果为:
[2, 16, 18, 22, 40, 48, 54, 58, 74, 76]
题目要求:
用随机数的方式,随机生成15位的大乐透号码;
题目分析:
跟上面一样,需要采用随机数的生成,但在这里我们可以导入一个生成随机数的类,即:Random类,最后对它遍历即可。
代码如下:
int[] arr = new int[15];
Random random = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(99) + 1;
}
System.out.println(Arrays.toString(arr));
结果为:
[96, 75, 69, 98, 83, 95, 43, 39, 48, 95, 42, 3, 13, 60, 91]
题目要求:
声明一个int类型的数组front,长度为35,默认值都是0;
声明一个int类型的数组after,长度为12,默认值都是0;
题目分析:
这次,我们需要从front里选出5个数字,从after里选出2个数字,再生成随机数的大乐透。
那么我们就要先声明两个存放他们数据的数组,因为不知道次数,所以我们用do while循环来遍历它们输出想要的数据,再跟上面一样输出即可。
代码如下:
int[] front = new int[35];
int[] after = new int[12];
for (int i = 1; i <= 5; i++) {
int index;
do {
index = (int) (Math.random() * front.length);
} while (front[index] == 1);
front[index] = 1;
}
for (int i = 1; i <= 2; i++) {
int index;
do {
index = (int) (Math.random() * after.length);
} while (after[index] == 1);
after[index] = 1;
}
System.out.println("本期大乐透的号码");
System.out.print("前区号码为:");
for (int i = 0; i < front.length; i++) {
if (front[i] == 1) {
System.out.print(i + 1 + "\t");
}
}
System.out.print("\n后区号码为:");
for (int i = 0; i < after.length; i++) {
if (after[i] == 1) {
System.out.print(i + 1 + "\t");
}
}
System.out.println();
结果为:
本期大乐透的号码
前区号码为:4 15 16 19 26
后区号码为:3 8
题目要求:
判断输入的单词是否为回文单词
题目分析:
跟判断回文数一个道理,可以用长度/2来判断,可以用前后两个指标的数值来判断。
即,当左指标的数值!=右指标时,退出循环输出不是回文数。
代码如下:
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个英文单词");
String word = scanner.next();
char[] wordChar = word.toCharArray();
boolean flage = true;
for (int left = 0, right = wordChar.length - 1; left < right; left++, right--) {
if (wordChar[left] != wordChar[right]) {
flage = false;
break;
}
}
if (flage) {
System.out.println("是一个回文单词");
} else {
System.out.println("不是一个回文单词");
}
结果为:
wow
是一个回文单词
题目要求:
公司年会有一个寻找锦鲤的游戏,每一个员工随意写一个字,如果在“锦鲤”词库中有这个字,那么就奖励500元锦鲤红包,否则就没有,每人只能玩一次。现有锦鲤字库如下,它们按照Unicode编码值从小到大排序:char[] koiFishWords = {'一','今','地','定','年','开','我','果','火','爱','结','花','遍'};
题目分析:
我们对于这个问题,我的想法是,用一个for循环来遍历数组的元素,再与输入的元素进行对比,若有相等的元素,则退出循环输出赢得奖金;若遍历完数组仍没有相等的元素,则输出没有赢得奖金即可。
代码为:
char[] koiFishWords = {'一','今','地','定','年','开','我','果','火','爱','结','花','遍'};
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你写的字:");
String x =scanner.next();
char zi = x.charAt(0);
boolean flage=false;
for (int i = 0; i < koiFishWords.length ; i++) {
if (koiFishWords[i]==zi){
flage=true;
break;
}else{
flage=false;
break;
}
}
if (flage){
System.out.println("恭喜抽到锦鲤,奖励500!");
}else{
System.out.println("您没有抽到锦鲤,没有奖励!");
}
结果为:
请输入你写的字:
一
恭喜抽到锦鲤,奖励500!
请输入你写的字:
嘻嘻
您没有抽到锦鲤,没有奖励!
题目要求:
直线上有n个点,数组中存放着索引点举例下一个点的距离,现有L长度的绳子,问最多覆盖直线上的几个点?
题目分析:
我的想法是定义一个number来存放,覆盖的点数,定义一个sum来存放覆盖的路径长度,用for循环遍历数组,当sum+arr[i]<=L时,绳子就可以覆盖住该点,number++,sum+=arr[i]。
代码如下:
主方法:
int[] arr = {1, 2, 2, 7, 9, 11};
Scanner scanner = new Scanner(System.in);
System.out.println("请输入绳子的长度:");
String L = scanner.next();
System.out.println(point(arr, Integer.parseInt(L)));
方法内:
Arrays.sort(arr);
int number = 0;
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] + sum <= L) {
number++;
sum += arr[i];
} else {
break;
}
}
return number + 1;
结果为:
请输入绳子的长度:
3
3
我们给出的是已经确定数组内容的死方法,同样也可以通过Random类给出随机数的方式将它变成变化着的数组。
即采用上面大乐透生成随机数的方法即可。
Random rand = new Random();
题目要求:
保存全班的每个组的成绩,并对成绩做统计
使用二维数组保存全班的每个组的成绩,从键盘输入一共有几组,从键盘输入每一组分别有多少人
从键盘输入每一个同学的成绩,并对成绩做如下统计:
统计每一组的最高分、最低分;统计每一组的平均分;统计全班的最高分、最低分;统计全班的平均分;统计全班的总人数。
题目分析:
这个就是单纯的定义二维数组以及for循环等其他循环结构的嵌套使用,上面一篇文章已经介绍过了,
代码如下:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入小组的组数:");
int groupnum = scanner.nextInt();
int[][] student = new int[groupnum][];
for (int i = 0; i < groupnum; i++) {
System.out.println("请输入第" + (i + 1) + "组有多少人:");
int peoplenum = scanner.nextInt();
student[i] = new int[peoplenum];
}
for (int i = 0; i < student.length; i++) {
for (int j = 0; j < student[i].length; j++) {
System.out.println("请输入第" + (i + 1) + "组第" + (j + 1) + "个人的成绩:");
student[i][j] = scanner.nextInt();
}
}
for (int i = 0; i student[i][j]) {
groupmin = student[i][j];
}
if (classmax < student[i][j]) {
classmax = student[i][j];
}
if (classmin > student[i][j]) {
classmin = student[i][j];
}
groupsum += student[i][j];
classpeople++;
classsum += student[i][j];
}
System.out.println("第" + (i + 1) + "组的最高分为:" + groupmax + "\n" + "最低分为:" + groupmin + "\n" + "平均分为:" + (groupsum / student[i].length));
}
System.out.println("----------------------------------------------------");
System.out.println("全班最高分为:" + classmax + "\n" + "最低分为:" + classmin + "\n" + "平均分为:" + (classsum / classpeople) + "\n" + "班级总人数为:" + classpeople);
}
}
结果为:
请输入小组的组数:
2
请输入第1组有多少人:
2
请输入第2组有多少人:
1
请输入第1组第1个人的成绩:
30
请输入第1组第2个人的成绩:
50
请输入第2组第1个人的成绩:
67
第1组的学生成绩为:
学生1的成绩为:
30
学生2的成绩为:
50
第2组的学生成绩为:
学生1的成绩为:
67
第1组的最高分为:50
最低分为:30
平均分为:40
第2组的最高分为:67
最低分为:67
平均分为:67
----------------------------------------------------
全班最高分为:67
最低分为:30
平均分为:49
班级总人数为:3
我们同样也可以用一维数组来进行编写,代码如下:
Scanner scanner = new Scanner(System.in);
System.out.println("请输入小组的组数:");
int groupnum = scanner.nextInt();
int[] group = new int[groupnum];
for (int i = 0; i < groupnum; i++) {
System.out.println("请输入第" + (i + 1) + "组的人数:");
int peoplenum = scanner.nextInt();
group[i] = peoplenum;
}
int[] groupavg = new int[groupnum];
int[] groupmax = new int[groupnum];
int[] groupmin = new int[groupnum];
for (int i = 0; i < groupnum; i++) {
int[] scores = new int[group[i]];
for (int j = 0; j < group[i]; j++) {
System.out.print("请输入第" + (i + 1) + "组第" + (j + 1) + "个同学的成绩:");
scores[j] = scanner.nextInt();
}
int max = scores[0];int min = scores[0];int mid = 0;
for (int j = 0; j < group[i]; j++) {
if (max < scores[j]) {
max = scores[j];
}
groupmax[i] = max;
if (min > scores[j]) {
min = scores[j];
}
groupmin[i] = min;
mid += scores[j];
}
groupavg[i] = mid / group[i];
System.out.println("第" + (i + 1) + "组的最高分是:" + groupmax[i]);
System.out.println("第" + (i + 1) + "组的最低分是:" + groupmin[i]);
System.out.println("第" + (i + 1) + "组的平均分是:" + groupavg[i]);
System.out.println();
}
int summax = groupmax[0];
int summin = groupmin[0];
int sum = 0;
int sumavg = 0;
int sumnum = 0;
for (int i = 0; i < groupnum; i++) {
if (summax < groupmax[i])
summax = groupmax[i];
if (summin > groupmin[i])
summin = groupmin[i];
sum += groupavg[i];
sumnum += group[i];
}
sumavg = sum / groupnum;
System.out.println("全班信息统计如下:\n");
System.out.print("\n全班最高分:" + summax);
System.out.println("\n全班最低分:" + summin);
System.out.println("\n全班平均分:" + sumavg);
System.out.println("\n全班总人数:" + sumnum);
System.out.println();
}
结果为:
请输入小组的组数:
2
请输入第1组的人数:
2
请输入第2组的人数:
2
请输入第1组第1个同学的成绩:23
请输入第1组第2个同学的成绩:45
第1组的最高分是:45
第1组的最低分是:23
第1组的平均分是:34
请输入第2组第1个同学的成绩:34
请输入第2组第2个同学的成绩:56
第2组的最高分是:56
第2组的最低分是:34
第2组的平均分是:45
全班信息统计如下:
全班最高分:56
全班最低分:23
全班平均分:39
全班总人数:4