第5周 数组
5.1 数组
数组
- 是一种容器(放东西的东西),其中所有元素具有相同数据类型
- 一旦创建,不能再改变大小
- 数组中的每个数据叫做元素
length
属性可以访问数组长度l=a.length();
这种使用方式使得代码具有可扩展性(代码不需要做修改就能适应今后程序的变化)
定义数组变量:
- <类型>[] <名字> = new <类型>[元素个数];
- int[] grade = new int[100];
- double[] averages = new double[20];
- 元素个数必须给出
- 元素个数必须是整数
- 元素个数可以是变量(先让用户输入数组的个数,然后将这个数确定为数组的元素个数)
int[]a = new int[10];
- 创建了一个名字叫numbers的int型数组
- 元素个数为10
- 每个元素都是一个int变量
- 可以读和写
a[2]=a[1]+6
- 数组长度
l=a.length;
数组元素
-
每个元素都是那种类型的变量
-
数组的索引或下标都是从0开始的(源自于C语言,其编译器从0开始更易于计算)
numbers[0];//表示数组中的第一个元素
/*10个元素:a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]
每个元素是一个int类型的变量*/
- 最小的下标是0,最大的下标是元素个数-1
- 编译器不会检查下标是否有效,如果运行时出现了无效下标,会导致程序终止。
直接初始化数组
package Pracrice;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] scores = {87,98,69,54,65,76,87,99};//直接初始化数组
System.out.println(scores.length);//.length可以输出数组的元素个数,在遍历数组时使用.length方便日后扩展
for(int i=0;i<scores.length;i++)
{
System.out.print(scores[i]+" ");
}
}
}
数组变量
- 数组变量是数组的管理者而非数组本身
- 数组必须创建出来然后交给数组变量来管理
- 数组变量之间的赋值是管理权限的赋予
- 数组变量之间的比较是判断是否管理同一个数组
int[] a1 = {1,2,3,4,5};
int[] a2 = a1;
for ( int i=0; i<a2.length; ++i )
{
a2[i] ++;
}
for ( int i=0; i<a1.length; ++i )
{
System.out.println(a1[i]);
}
//示意图如下
复制数组
- 必须遍历源数组,将每个元素逐一拷贝给目标数组
5.2 数组计算
遍历数组:for循环
- 通常使用for循环,让循环变量i从0到<数组的length,这样循环体内最大的i正好是数组最大的有效下标。
for(int i=0 ; i<list.length;i++)
- 常见错误:
- 循环结束条件是<=数组长度;
- 离开循环后,继续使用i的值来做数组元素的下标
//输入一个数,查看其是否在数组中
int[] data = {2,3,4,5,6,7,8,9,10};
int x = in.nextlnt();
int loc = -1;
for(int i=0;i<data.length;i++)
{
if(x==data[i])
{
loc = i;
break;
}
}
if(loc>-1)
{
System.out.println(x+"是第"+(loc+1)+"个");
}
else
{
System.out.println(x+"不在其中");
}
遍历数组:for-each循环
for(<类型><变量>:<数组>){
...
}//对于数组中的每一个元素取出来作为这个类型的变量
非常适合用于遍历读出数组,但是不能修改数组
for循环和for-each循环的对比
//输入一个数,查看其是否在数组中
int[] data = {2,3,4,5,6,7,8,9,10};
int x = in.nextlnt();
boolean found = false;
for(int k : data )//对于data数组中的每一个元素,循环的每一轮将其取出作为一个k。所以每一轮的k都是变化的,第一轮k=data[0];第二轮k=data[2]
{
if(x == k )
{
found = true;
break;
}
}
if(found)
{
System.out.println(x+"在其中");
}
else
{
System.out.println(x+"不在其中");
}
素数:人的思维
- 原始方法
- 循环n-1遍
- 当n很大时,循环n遍
- 循环n-1遍
import java.util.Scanner;
public class isPrime {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int x = in.nextInt();
boolean isPrime = true;
if(x==1)
isPrime=false;
for(int i=2;i<x;i++){
if( x % i == 0){
isPrime = false;
break;
}
}
if(isPrime){
System.out.println(x+"是素数");
}else {
System.out.println(x+"不是素数");
}
}
}
- 排除所有偶数
- 如果x是偶数(2除外),那么x不是素数
- 否则要循环(n-3)/2+1遍(用奇数)
- 当n很大时,循环n/2遍
if (x == 1 || x%2 == 0 && x!=2)
{
isPrime=false;
}
else
{
for (int i=3; i<x;i+=2)
{
if(x%i==0)
{
isPrime=false;
break;
}
}
}
- 无须到x-1,到sqrt(x)就够了(具体数学证明自学)
- 循环sqrt(n)遍
for( int i=3;i< Math.sqrt(x);i+=2)
{
if(x%i ==0)
{
isPrime=false;
break;
}
}
- 判断是否能被已知的且<x的素数整除,若都不能,那么x是素数
- 循环更优化
Scanner in = new Scanner(System.in);
int[] primes = new int[50];
primes[0]= 2;
int cnt = 1;
MAIN_LOOP:
for(int x = 3;cnt<50;x++)
{
for(int i= 0;i<cnt;i++)
{
if(x%primes[i]==0)
{
continue MAIN_LOOP;
}
}
primes[cnt++]=x;
}
for(int k:primes)
{
System.out.print(k+" ");
}
素数:计算机的思维
-
欲构造n以内(不含)的素数表
- 令x为2
- 将2x、3x、4x直至ax<n的数标记为非素数
- 令x为下一个没有被标记为非素数的数,重复2;直到所有的数都已经尝试完毕
-
欲构造n以内(不含)的素数表
-
创建prime为boolean[n],初始化其所有元素为true,prime[x]为true表示x是素数
-
令x=2
-
如果x是素数,则对于(i=2;xi<n;++)令
prime[ix]=false
-
令x++,如果x<n,重复3,否则结束
-
import java.util.Scanner;
public class isPrime_machine {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean[] isPrime = new boolean[100];
for(int i = 0;i<isPrime.length;i++)
{
isPrime[i] = true;
}
for(int i=2;i<isPrime.length;i++)
{
if(isPrime[i])
{
for(int k=2;i*k<isPrime.length;k++)
{
isPrime[i*k]= false;
}
}
}
for(int i= 2;i<isPrime.length;i++)
{
if(isPrime[i])
{
System.out.print(i+" ");
}
}
}
}
5.3 二维数组
二维数组初始化
int[][] a = new int[3][5];
通常理解为a是一个3行5列的矩阵,如下图所示:
int[][] a {
{1,2,3,4},
{1,2,3},
};//2*4的数组
- 编译器来数数
- 每行一个{},逗号分隔
- 最后的逗号可以存在,来自C语言的古老传统
- 如果省略,表示补零
二维数组的遍历
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
a[i][j]=i*j;
}
}
for(i=0;i<a.length;i++)
{
for(j=0;j<a[i].length;j++)
{
a[i][j]=i*j;
}
}
a[i][j]
是一个int- 表示第i行第j列上的单元
- 不存在a[i,j]的写法