数组&算法应用&Debug
1.数组
1.1 数组的概念和作用
• 数组是一组类型相同的数据的集合;
• 也就是说,数组中可以存储多个数据,但是这些数据的类型必须相同;
• 数组能够作为数据的容器使用,把多个数据集中存储;
• 存储在数组中的数据,都有相应的索引值,可以方便获取或修改;
• 当需要同时保存多个类型相同的变量并进行处理时,可以考虑用数组,例如:多个人的成绩、多个员工的薪资……
1.2 Java的数组特性
• Java的数组是引用类型;
• 数组与类、接口、枚举、注解并列,是引用类型中的一种;
• Java的数组长度一经确定不能改变;
• 例如,一个数组的长度是10,那么最多能存10个数据,如果保存第11个就会出错;
• 数组在内存中是连续分配,所以读取速度快
1.3 数组元素
• 数组中存储的数据称为数组的元素(Element);
• 数组本身是引用类型,但是数组中的元素可以是基本数据类型,也
可以是引用类型;
• 也就是说,即可以有存储基本数据类型int的数组,也可以有存储引用类型String的数组,但是数组本身是引用类型;
• 数组中的元素有索引值,索引值从0开始;
• 也就是说,如果一个数组的长度是10,那么索引值就是0-9,也就是第一个元素的索引值是0,第二个的索引值是1,以此类推,通过索引值可以方便访问元素;
1.4 一维数组
1.41 一维数组的声明形式
数组元素类型[ ] 变量名称;
或
数组元素类型 变量名称[ ] ;
例如:
int[] a; 或 int a[];
String[] s; 或 String s[];
• 不论数组中元素是什么类型,以上声明形式都适用;
1.42 一维数组的初始化
第一种:数组元素类型[ ] 变量名称=new 数组元素类型[数组长度];
第二种:数组元素类型[ ] 变量名称=new 数组元素类型[]{用逗号隔开元素的具体值};
第三种:数组元素类型[ ] 变量名称= {用逗号隔开元素的具体值};
int[] array=new int[10];
int[] array2=new int[] {1,23,45};
int[] array3= {1,23,456};
• 数组是引用类型,a保存数组的首地址,指向堆中数组的具体内容;
• 数组元素使用索引表示,如a[0]、a[1]…...
1.43 数组的访问
数组是引用类型,数组名array保存的是数组的首地址,指向堆中数组的具体内容;
数组元素使用索引表示,索引从0开始如:array[0],array[1].....
语法:
数组变量名[索引];
注意:如果访问数组的下标越界,会出现异常信息
array[0]=1;
array[1]=22;
array[2]=9;
System.out.println("访问数组中的第一个元素:"+array[0]);
System.out.println("访问数组中的第2个元素:"+array[1]);
System.out.println("访问数组中的第3个元素:"+array[2]);
System.out.println("访问数组中的第10个元素:"+array[9]);
1.44 数组的长度
使用数组变量名.length属性可以返回数组的长度;
System.out.println("数组长度:"+array.length);
System.out.println("数组长度:"+array2.length);
1.45 数组的遍历
1.for循环
System.out.println("**********方式1:for循环遍历数组***********");
for (int index = 0; index < array.length; index++){
System.out.println(array[index]);
}
for(int i=0;i<array2.length;i++) {
System.out.println(array2[i]);
}
2.增强for循环
System.out.println("**********方式2:foreach循环遍历数组***********");
for(int k: array ) {
System.out.println(k);
}
1.46 数组的排序
java API中有个类Arrays.定义了大量的 sort(),可以对数组中的元素进行排序;
import java.util.Arrays;
public class TestArray_01 {
public static void main(String[] args) {
int [] intArray= {59,23,122,44,555,3,0,-1};
for (int i : intArray) {
System.out.print(i+" ");
}
System.out.println();
Arrays.sort(intArray);
for (int i : intArray) {
System.out.print(i+" ");
}
System.out.println();
char[] charArray= {'6','A','Z','a','7'};
for (char c : charArray) {
System.out.print(c+" ");
}
System.out.println();
Arrays.sort(charArray);
for (char c : charArray) {
System.out.print(c+" ");
}
}
}
1.5 数组&常见算法问题
1.51 和和平均值(累加,总和除以个数)
1. 从控制台接收5个学生的java成绩,求和和平均分;
public class TestArray{
public static void main(String[] args) {
double[] score=new double[5];
double sum=0;
Scanner scanner=new Scanner(System.in);
for (int i = 0; i < score.length; i++) {
System.out.println("请输入第"+(i+1)+"个学生的java成绩:");
score[i]=scanner.nextDouble();
sum+=score[i];
}
System.out.println("总成绩:"+sum+",平均成绩:"+sum/(score.length));
}
}
1.52 最值(最大值 最小值)
思考:
假设第一个元素的值为最大,然后接下来用相邻的值和第一个值比较,保留大的那个值;再用这个值和下一个相邻的元素比较,保留最大的;以此类推 ;直到最后一个元素,得到了所有数字中的最大值;
public class TestArray {
public static void main(String[] args) {
double[] score=new double[5];
Scanner scanner=new Scanner(System.in);
for (int i = 0; i < score.length; i++) {
System.out.println("请输入第"+(i+1)+"个学生的java成绩:");
score[i]=scanner.nextDouble();
}
double max=score[0];
double min=score[0];
for (int i = 1; i < score.length; i++) {
if (score[i]>max) {
max=score[i];
}
if (score[i]<min) {
min=score[i];
}
}
System.out.println("最高分:"+max);
System.out.println("最低分:"+min);
}
}
1.53 查找
String[] names={“小白”, “小宏”, “小兰”, “小黑”, “小绿”, “小白”};
String find=”小白”
public class TestArray {
public static void main(String[] args) {
String[] names={"小白", "小黑", "小绿", "小红", "塞班", "塞班"};
boolean flag=false;
String find="小红2";
for (int i = 0; i < names.length; i++) {
if (names[i].equals(find)) {
System.out.println("在第"+(i+1)+"个位置上找到了"+find);
flag=true;
}
}
if (!flag) {
System.out.println("没找到"+find);
}
}
}
1.54 插入算法(了解)
在一个已经按照特定顺序排好的数组中,我们要插入一个新的元素进来,要求,插入新的元素之后,数组元素依然是有序的.
int array[]={1,3,5,7,9,0}
public class Test {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int[] arr = {1,3,5,7,9,0};
int position=5;
System.out.println("请输入要插入的数:");
int insert=scanner.nextInt();
for (int i = 0; i < arr.length-1; i++) {
if (arr[i]>insert) {
position=i;
break;
}
}
for (int i = arr.length-1; i >position; i--) {
arr[i]=arr[i-1];
}
arr[position]=insert;
for (int i : arr) {
System.out.print(i+" ");
}
scanner.close();
}
}
1.55 排序算法
冒泡排序:
int[] arr ={12,7,-1,8,99}
希望以上一组数能够按照一定的顺序(从大到小/从小到大)重新排列;
相邻的两个元素依次比较,根据比较条件,来交换位置;
1.第一轮开始:比较了4次,结果是得到了5个数中的最大值
12和7比,用>比较,如果条件为真,则交换两个元素
12和下一个相邻元素 12>-1, 则交换两个元素
....
2.第二轮开始:比较了3次,结果是得到了剩下4个数中的最大值;
...
3.第三轮开始: 比较了2次,结果是得到了剩下3个数中的最大值;
4.第四轮开始: 比较了1次,结果是得到了剩下2个数中的最大值;
总结:5个数字,比较了4轮;
每一轮内部比较了几次: 4 3 2 1
满足条件我们做什么?交换两个相邻的元素
嵌套循环; 外控制比较的轮数(长度-1) ;内循环控制的是每轮比较的次数(长度-i-1) ;
i是外循环变量; 内循环中比较相邻的元素( 使用内循环变量作为下标 array[j]>array[j+1]) ;
结果 应该是从小到大;
public class Test{
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
float[] arr =new float[5];
for (int i = 0; i <5; i++) {
System.out.println("请输入第"+(i+1)+"个数:");
arr[i] = sc.nextFloat();
}
float temp=0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if (arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for (float f : arr) {
System.out.println(f);
}
}
}
1.6 二维数组:
二维数组,在内存中的结构和一维数组是一致的;但是我们可以将其理解为一个平面结构;
• 如果一个数组中存储数据结构如下所示,元素是一维数组,称为二维数组;
• 其中,第0个元素是数组{67,78,54},第1个元素是数组{89,12};
二维数组可以理解成一个表格:有行有列,行有下标,列也有下标;
1.61 定义和赋值
数组元素类型[ ][ ] 变量名称=new 数组元素类型[一维长度] [二维长度];
数组元素类型[ ][ ] 变量名称=new 数组元素类型[行数] [列数];
如果同时确定一维和二维的长度,则表示数组的元素是等长的一维数组
int[ ][ ] array=new int[5] [6];
如果数组元素不是等长的一维数组,可以不指定二维长度;
int[ ][ ] array=new int[5] [];
public class TestArray {
public static void main(String[] args) {
int[][] array01=new int[3][4];
int[][] array02=new int[3][];
System.out.println(array01[0][0]);
System.out.println(array01[0][1]);
array01[0][0]=10;
array01[0][1]=20;
array01[0][2]=30;
array01[0][3]=40;
array01[1][0]=50;
array01[2][3]=1000;
System.out.println("一维数组的数量:"+array01.length);
System.out.println("一维数组的二维长度:"+array01[0].length);
System.out.println("一维数组的二维长度:"+array01[1].length);
for(int i=0;i<array01.length;i++) {
for (int j = 0; j < array01[i].length; j++) {
System.out.print(array01[i][j]+"\t");
}
System.out.println();
}
}
}
1.62 案例:杨辉三角
思考:
行(i) 列(j) 第一列值为1,以及每一行的最后一列,if(i==j || j==0)
Array[i][j]=array[i-1][j]+ array[i-1][j-1]
1(0,0) | | | | |
---|
1(1,0) | 1(1,1) | | | |
1 | 2(2,1) | 1(2,2) | | |
1 | 3 | 3 | 1(3,3) | |
1 | 4 | 6 | 4 | 1(4,4) |
public class TestArray {
public static void main(String[] args) {
int[][] array=new int[20][20];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j <=i; j++) {
if(i==j || j==0) {
array[i][j]=1;
}else {
array[i][j]=array[i-1][j]+ array[i-1][j-1];
}
System.out.print(array[i][j]+"\t");
}
System.out.println();
}
}
}
练习:
1. 实现等腰三角形的杨辉三角 [5][]
public class Test_how1 {
public static void main(String[] args) {
int[][] arr=new int[20][];
for (int i = 0; i < arr.length; i++) {
arr[i]=new int[i+1];
for (int j = 0; j < arr.length-1-i; j++) {
System.out.print(" ");
}
for (int j = 0; j <=i; j++) {
if (i==j || j==0) {
arr[i][j]=1;
}else {
arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
}
System.out.printf("%6d",arr[i][j]);
}
System.out.println("");
}
}
}
2. 定义二维数组,统计班级5个学生的Java,C#,Python课程的成绩,并求每门课程的平均分;
数组定义: double score[][] = new double[3][5];
public class TestArray02 {
public static void main(String[] args) {
double score[][]=new double[3][5];
Scanner scanner=new Scanner(System.in);
for (int i = 0; i < score.length; i++) {
double sum=0;
System.out.println("请输入第"+(i+1)+"门课程的成绩:");
for (int j = 0; j < score[i].length; j++) {
System.out.println("请输入第"+(j+1)+"个学生的成绩:");
score[i][j]=scanner.nextDouble();
sum+=score[i][j];
}
System.out.println("第"+(i+1)+"门课程的平均成绩:"+sum/5);
}
scanner.close();
}
}
2. Debug
2.1 设置断点,右键选择 debug as
2.2 调试界面:
2.3 停止调试
2.4 小球落地
1.一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?
第10次落地反弹多高?(DEBUG)
public class Test {
public static void main(String[] args) {
double height=100;
double sum=100;
int i=1;
while(i<=10) {
height=height/2;
i++;
if (i<=10) {
sum=sum+height*2;
}
}
System.out.println("第10次落地时,弹起的高度为:"+height+"m");
System.out.println("第10次落地时,经过的路径长度为:"+sum+"m");
}
}
2.5 猴子吃桃
猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个 ;第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。请使用for和while分别处理;
分析: 一共吃了九天;倒着推理;
第10天早上开始: 没吃, 1
第9天早上: 没吃, (1+1)*2=>4
第8天早上开始: 没吃, (4+1)*2 =>10
…
第1天早上,摘了,还没吃 (?+1)*2 =>
以上的分析可以得到:
1. 循环执行几次;
2. 计算桃子个数的表达式 (?+1)*2
public class Test {
public static void main(String[] args) {
int sum=1;
for (int day = 9; day >=1; day--) {
sum=(sum+1)*2;
}
System.out.println("第1天没吃,一共有:"+sum+"个桃子");
}
}