首先继续来谈一下循环:while循环、do…while循环、for each循环。
while循环
与for循环一样,while也是一个预测试的循环,但是while在循环开始之前,并不能确定重复执行循环开始语句序列的次数。while按不同的条件执行循环语句序列零次或多次。
- 例:求1+2+……的和,值之和大于1000为止。
package kkzz;
public class SumWhile {
public static void main(String[] args) {
int sum = 0;
int i = 0;
while (sum <= 10000){
sum += i;
i++;
}
System.out.printf("%d",sum);
}
}
10011
do…while循环
do语句按不同条件执行一次或多次循环语句序列。do…while循环的测试条件在执行完循环后执行,循环体至少执行一次,而while循环的循环体可能一次也不执行。
do…while循环语句的格式:
do{
循环体语句序列;
}while(条件表达式);
- 例:求1-100的和、奇数和、偶数和。
package com.k;
public class Dowhile {
public static int sum(int n) {
int sum = 0;
int i = 1;
do {
sum = sum + i;
i++;
} while (i <= n);//1-100求和
return sum;
}
public static int sumodd(int n) {
int sumOdd = 0;
int i = 1;
do {
sumOdd = sumOdd + i;
i += 2;
} while (i <= n);//1-100奇数求和
return sumOdd;
}
public static int sumeven(int n) {
int sumEven = 0;
int i = 2;
do {
sumEven = sumEven + i;
i += 2;
} while (i <= n);//1-100偶数求和
return sumEven;
}
public static void main(String[] args) {
System.out.println(sum(100));
System.out.println(sumodd(100));
System.out.println(sumeven(100));
}
}
5050
2500
2550
for each 语句
用于循环访问数组或集合,以获取所需信息。基本语句格式:for(变量:数据或集合){ 循环体语句序列;}
跳转语句
跳转语句用于无条件的转移控制。使用跳转语句执行分支,该语句会导致立即传递程序控制。Java提供了许多立即跳转到程序中另一行代码的语句,包括break、continue、return、throw。Java语言不支持goto语句。
break
break语句用于结束全部循环。
- 例:1+2+3+……n>1000时,输出m 的值。
package com.k;
public class Dowhile {
public static int fun1(){
int i = 1;
int tmp = 0;
for(;tmp <= 1000;i ++){
tmp += i;
}
return i - 1;
} //只用for循环
public static int fun2(){
int i = 1;
int tmp = 0;
for(;;i ++){
tmp += i;
if(tmp > 1000){
break;
}
} //break 结束循环党tmp大于1000时,返回i的值
return i;
}
public static void main(String[] args) {
System.out.println(fun1());
System.out.println(fun2());
}
}
45
45
continue
continue语句用于结束本次循环。
- 例:求既能被3整除又能被5整除的数字。
package com.k;
public class Dowhile {
ublic static void main(String[] args) {
System.out.println("1-100之间既能被3整除又能被5整除的数:");
for (int i = 1; i <= 100; i++) {
if (i % 15 != 0) {
continue;
}
System.out.println(i);
}
}
}
1-100之间既能被3整除又能被5整除的数:
15
30
45
60
75
90
return语句
return语句用于终止方法的执行并将控制返回给调用方法。如果方法有返回类型,return语句必须返回这个类型的值。如果方法为void类型,应使用没有表达式的return语句;如果方法为void类型,方法体最后的return语句可以省略。
数组(Array)
数组是一种数据结构,包含相同类型的一组数据。数组本身是数组引用类型对象,数组元素可以是任何数据类型(简单类型或引用类型),包括数组类型。
数组有一个“秩(rank)”,确定和每个数组元素的索引个数,其值是数组类型的方括号对([])的个数。数组的秩又称为数组的维度。“秩”为1的数组称为一维数组,“秩”大于1的数组称为多维数组。维度大小确定的多维数组通常称为二维数组、三维数组等。
数组的每一个维度都有一个关联的长度(length),它是一个大于或等于0的整数。创建数组实例时,将确定维度和各维度的长度,它们在该数组实例的整个生存期内保持不变。换言之,对于一个已存在的数组实例,既不能更改它的维度,也不能调整它的维度大小。
Java 语言中提供的数组是用来存储固定大小的同类型元素。
数组的声明:
首先必须声明数组变量,才能在程序中使用数组。因为数组类型为引用类型,数组变量的声明只是为数组实例的引用留出空间。数组的声明有以下两种形式:1.类型[] 数组变量名; //一般用该种形式; 2. 类型 数组变量名[];
- 例:
int[] arr1; //声明一个整型数组
byte[] arrByte1; //声明一个byte类型数组
数组的实例化(创建)和初始化:
数组在声明后必须实例化才能使用。数组实例在运行时使用new运算符动态创建(即实例化)。
new运算符指定数组实例的长度。new运算符自动将数组的元素初始化为相应的默认值:简单数值类型的数组元素默认值设置为零;char类型数组元素被初始化为0(\u0000);boolean类型数组元素被初始化为false;而引用类型数组元素的默认值设置为null。使用new运算符创建数组时,还可以通过{}初始化数组的元素。
- 例:
int[] arr1; //声明数组
arr1 = new int[10]; //创建一个可以存储10个整数的数组(实例化数组)
int[] arr2 = new int[10]; //同时声明和创建数组
arr2 = new int[]{1,2,3,4}; //创建并初始化一个可以存储5个整数的数组
int[] arr3 = {1,2,3,4,5}; //声明并初始化一个存储4个整数的int数组(Java编译器将自动出啊年数组)
String str[][] = new String[3][4]; //多维数组
如果通过{ }初始化数组的元素,则使用new运算符创建数组不需要也不能指定数组元素的个数,Java编译器将自动推断出数组的元素个数。 声明数组时,可直接初始化(无需使用new运算符创建数组),Java编译器将自动创建数组(实例化)。
数组的基本访问操作
通过数组下标(或索引)来访问数组中的数据元素。可以使用for each循环访问数组的各个元素。数组下标从0开始,具有n个元素(即维度长度为n)的数组下标是 0~n-1。通过数组的length属性,可以获取数组的长度。注意:访问数组时,如果使用了超过数组下标范围的索引,即数组越界,则会引发ArrayIndexOutOfBoundsException。
- 例:
package kkee;
import java.util.Arrays;
public class NewArray {
public static void main(String[] args) {
int[] myList = {9, 2, 4, 5}; //声明并初始化数组myList
// 打印所有数组元素
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i] + " ");
}
// 计算所有元素的总和
int total = 0;
for (int i = 0; i < myList.length; i++) {
total += myList[i];
}
System.out.println("Total is " + total);
// 查找最大元素
int max = myList[0];
for (int i = 1; i < myList.length; i++) {
if (myList[i] > max)
max = myList[i];
}
System.out.println("Max is " + max);
Arrays.sort(myList); //Arrays.sort 数组排序
System.out.println(Arrays.toString(myList));
}
}
9
2
4
5
Total is 20
Max is 9
[2, 4, 5, 9]
- 例:用数组打印斐波那契数列的前20项。
package com.k;
import java.util.Arrays; //导入Arrays包
public class Array {
public static void fabonacci(int[] array){ //数组作为函数的参数
int i;
array[0] = 1;
array[1] = 1;
for(i = 2;i < array.length; i++){
array[i] = array[i - 1] + array[i - 2];
}
}
public static void main(String[] args) {
int[] array = new int[20];
fabonacci(array);
System.out.println(Arrays.toString(array));
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
- 例: for each输出数组元素:
package kkee;
import java.util.Arrays;
/**
- @Package: kkee
- @Author:kkz
- @Description:
- @Date:Created in 2018/10/16 17:04
*/
public class Arrayforeach {
public static void main(String[] args) {
int[] array1 = new int[]{1,2,3,4,5};
for(int i = 0;i < array1.length;i++) {
System.out.print(array1[i] + " " );
}
System.out.println();
for(int i : array1) {
System.out.println(i);
}//for each 换行输出数组元素
System.out.println(Arrays.toString(array1));//返回指定数组的字符串形式
}
}
1 2 3 4 5
1
2
3
4
5
[1, 2, 3, 4, 5]
- Arrays 类
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。具有以下功能:
(1)给数组赋值:通过 fill 方法。
(2)对数组排序:通过 sort 方法,按升序。
(3)比较数组:通过 equals 方法比较数组中元素值是否相等。
(4)查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找
法操作。
(5)复制数组:通过copyOf方法复制数组,截取或默认值填充,结果为相同数据类型的长度为指定长度的数组。
(6)复制数组的指定范围内容:通过copyO分Range方法从起始索引(包括)到结束索引(不包括),结果为相同的数据类型的数组。
(7)返回指定数组内容的字符串形式:通过toString方法。
练习
- 1.实现二分查找算法:有序的数组
pubclic static int binarySearch(int[] array,int key) {} 找到返回下标,没有找到-1; 数组名,键值
- 二分查找算法:
二分查找又称折半查找,它是一种效率较高的查找方法。
折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小 于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半。 折半查找是一种高效的查找方法。它可以明显减少比较次数,提高查找效率。但是,折半查找的先决条件是查找表中的数据元素必须有序。
折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
二分算法步骤描述
① 首先确定整个查找区间的中间位置 middle;
② 用待查关键字值与中间位置的关键字值进行比较;
若相等,则查找成功
若大于,则在后(右)半个区域继续进行折半查找
若小于,则在前(左)半个区域继续进行折半查找
③ 对确定的缩小区域再按折半公式,重复上述步骤。
最后,得到结果:要么查找成功, 要么查找失败。折半查找的存储结构采用一维数组存放。
package mypratice;
/**
* @Package: mypratice
* @Author:kkz
* @Description:
* @Date:Created in 2018/10/16 17:15
*
*/
public class OrderArray {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 11, 15, 17};
int key = 15; //查找元素
System.out.println("所查找元素在数组中的下标为:" + binarySearch(arr, key, 0, 10));
}
public static int binarySearch(int[] arr, int key,int start,int end) {
start = 0;
end = arr.length - 1;
while (start <= end) {
int middle = start + (end - start) / 2;
if (arr[middle] == key) {
return middle;
} else if (arr[middle] < key) {
start = middle + 1;
} else {
end = middle - 1;
}
}
return -1;
}
}
所查找元素在数组中的下标为:9
- 2.求连续子数组的最大和?
{10,2,-1,9,-10,-99}最小值:不能超过0x80000000
从头到尾遍历整个数组,用一个整数记录子数组和的最大值,如果子数组和大于这个值,则更新最大值,如果子数组和为负,子数组和清零,然后继续往后遍历。考虑数组全是负数、数组为空等边界情况即可。
package mypratice;
/**
* @Package: mypratice
* @Author:kkz
* @Description:
* @Date:Created in 2018/10/16 22:45
*/
public class ConstantArray {
public static int SumOfSubArray(int[] array) {
if (array.length==0 || array==null) {
return 0;
}
int currentSum = 0; //存储当前连续n项的和
int max = 0; //存储连续子数组和的最大值
for (int i = 0; i < array.length; i++) {
if(currentSum<=0){ //如过当前连续n项的和小于等于0,则没必要与后面的元素相加
currentSum = array[i]; //currentSum重新赋值
}else{
currentSum += array[i]; //如果currentSum的值大于0,则继续与后面的元素相加,
}
if(currentSum>max){ //每次改变currentSum的值都有与max进行比较
max = currentSum; //如果currentSum的值大于max,则将currentSum的值赋值给max
}
}
return max;
}
public static void main(String[] args) {
int[] array = {10,2,-1,9,-10,-99};
int result = SumOfSubArray(array);
System.out.println("连续子数组的最大和为:"+result);
}
}
连续子数组的最大和为:20
- 3.交换两个数?
package mypratice;
import java.util.Arrays;
/**
* @Package: mypratice
* @Author:kkz
* @Description:
* @Date:Created in 2018/10/16 22:24
*/
public class ChangeValue {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int temp = 0; //引入临时变量,赋初始值为0
temp = arr[1]; //将arr[1]的值赋给temp temp = 1
arr[1] = arr[4]; //将arr[4]的值赋给arr[1] arr[1] = 5
arr[4] = temp; //将temp的值赋给arr[4] arr[4] = 1
System.out.println(Arrays.toString(arr)); //返回指定数组的字符串形式
}
}
[1, 5, 3, 4, 2]
- 4.逆置数组?{1,2,3,4}===》{4,3,2,1}
package mypratice;
import java.util.Arrays;
/**
* @Package: com.k
* @Author:kkz
* @Description:
* @Date:Created in 2018/10/14 21:09
*
* 逆置数组?{1,2,3,4}===》{4,3,2,1}
* 将数组中的
*/
public class TestArray {
public static void main(String[] args) {
int n = 1/2;
int[] array = {1,2,3,4};//声明并初始化数组
for(int i = 0;i < (array.length)/2; i ++){
int tmp = array[i];//把数组中的值赋给临时变量
array[i] = array[array.length - i - 1];//将后面的值赋给数组前面
array[array.length - i - 1] = tmp;//将临时变量里的值赋给后面 即交换数组前一半与后面的元素
}
for(int i = 0;i < array.length; i ++) {}
System.out.println(Arrays.toString(array));
}
}
[4, 3, 2, 1]