5.1.1 初始数组
new 是创建
package diwuzhou1;
import java.util.Scanner;
public class Diwuzhou1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System. in);
int x;
double sum = 0;
int cnt = 0;
int [] numbers = new int[100];
x = in.nextInt();
while( x != -1)
{
numbers[ cnt] = x;
sum += x;
cnt++;
x = in.nextInt();
}
if( cnt > 0);
{
double average = sum/ cnt;
for( int i=0; i< cnt; i++)
{
if ( numbers[ i]> average)
{
System. out.println( numbers[ i]);
}
}
}
}
}
创建数组的代码
int [] numbers = new int[100]; 这里有个隐患,就是数组的元素不能超过100个。话说跟C比起来,这个创建好复杂
while( x != -1)表示对数组元素的初始化是以输入-1结束的
5.1.2创建数组
数组一旦创建,大小就不能改变(是一种容器)
数组中所有的元素都是一样的
定义数组变量
类型[]名字=new 类型[元素个数]
如double[] averages = new double[20];
元素个数必须是整数,个数必须给出,且可以是变量
前边这个方框内是不能给数字的
与C相同,数组也是从0开始的,第一个元素是a[0]
下标又叫做索引
5.1.3数组的元素
100个数组的元素是下标是从0开始,到99.
编译器并不检查下标是否有效,运行的时候下标越界会是程序终止
数组元素的个数是可以由用户输入的,这个大小是程序运行的时候才知道,但是这个大小也是不能改变的
数组的固有成员,叫做length
比如一个100元素的数字,遍历的时候可以
for(i=0;i<100;++i)
sum += grade[i];
最好是:
for(i=0;i < grade.length;++i)
sum += grade[i];
grade是数组名
数组元素的初始化全部为0.与C一样
5.1.4 例子:投票统计
输入一些[0,9]内的整数,统计各个数字出现多少次
代码
int [] numbers = new int[10];
int x;
x = in.nextInt();
while(x != -1)
{
if (x>=0 && x<=9)
{
numbers[x]++;
}
x = in.nexrInt();
}
for (int i=0;i < numbers.length; i++)
{
System.out.println(i+”:”+numbers[i]);
}
5.2.1数组变量
直接初始化数组
如int [] sorces = {1,2,55,87}
这跟new创建的数组是不一样的,new常见的数组默认是0
这种方法直接用大括号给出数组的所有元素的初始值,可以用length得到数组的大小,这是C中的数据不具备的。使用length具备可扩展性
JAVA是没有指针的,C中的数组本质上就是指针,所以两者的数组不同之处很多。
JAVA中数组变量和数组不是同一个东西,数组变量是管理者,不是数组本身。
如int [] a = new int [10];
a[0] = 5;
int[]b = a;
b[0]=16,则输出a[0]的结果将是16
这是因为现在b也是数组的管理者,与a一样都是管理者,它们都可以改变数组内的元素。
b也是这个数组的管理者,当然可以改变b[0]的值。可以说数组中的这个单元既叫做b[0],也叫做a[0]
数组管理者(数组变量)里边没有数据,只是管理某个地方的数组,不是所有者
new的意思是在某个地方制造一个别的东西给你
JAVA没有指针,用管理者的概念
tips
数组变量是数组的管理者而非数组本身
数组必须创建出来然后交给数组变量去管理(两者是分开的)
数组变量之间的赋值是管理权限的赋予
数组变量之间的比较是判断是否管理同一个数组(不是内容)
如int[] a= {1,2,3}
int[] b = a ,则a==b的结果为true
int[] b = {1,2,3}的话,a==b的结果就是false,虽然两者的内容一致,但是不是相同的管理权限,就认为a和b这两个数组变量不相同
复制数组:
只能使用遍历的方法这个拷贝(拷贝过来的仅仅是数组元素的值想等,不是管理权限想等。也就是即便for循环让b[i]=a[i]了,a==b的结果仍然是false)
如果判断两个数组是否想等,只能使用for循环,逐个判断对应元素的大小是否相等。每个对应的数组元素都相等,就认为是数组想等。虽然a==b的结果仍然是 false
5.2.2遍历数组
可以像C一样,使用三段式for循环来判断
for(i=0;i < data.length;i++)
if(x == data[i])…..
这个还可以知道某个数字在数组中的位置。
JAVA中还有个遍历的办法,for-each循环
格式是for (类型 变量:数组)
for(int k :data)
if (k==x)
{
found =true;
break;
}
对于data这个数组中的每一个元素,循环中的每一轮把它拿出来,作为k,所以每一轮,k是不断变化的。第一轮,k=data[1],第二轮k=data[2].这也是一种按轮把数组中的元素找出来的方法。与三段式的for相比,这样的效率还高一点。缺点是:
不能知道某个数字在第几位;
不能对数组中的数据进行修改(当然输出是可以的)
5.2.3 素数
循环改进的方案:
判断的时候可以不用判断偶数,从3到x-1,可以每次加2.
也可以值判断到根号下x, sqrt(x)
还可以根据已经产生的素数决定下一个素数。
对于x,比它小的素数数量当然少于比它少的自然数。
package diwuzhou2;
public class Diwuzhouu2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] primes = new int [50];
primes[0] = 2;
int cnt = 1;
MAIN_LOOP:
for ( int x=3; cnt< primes. length; x++)
{
for ( int i=0; i< cnt; i++)
{
if ( x% primes[ i] == 0)
{
continue MAIN_LOOP;
}
}
primes[ cnt++] = x; //发现一个素数,写在以 cnt为下标的数组primes的
} //那一位去,同时 cnt++,也就是下一个运算操作的是primes数组的下一位
//cnt即表达有多少个素数,也表达下一位的素数应该放到数组的哪一位去(还好数组从0开始计数)
for ( int k : primes)
{
System. out.print( k+ " ");
}
System. out.println();
}
}
程序的一点解释:
primes是用来存放素数的数组。cnt是它的下标,同时也可以表示数组内有几个元素。这取决于primes[ cnt++] = x;这里的x是先使用,再自加。
如,cnt=3,则primes[3]=x,x的值放在数组第四位(primes[0]primes[1]primes[2]primes[3]),然后cnt自加,变成4.
另外,x%primes[i] == 0,判断x是否能被数组中的某个素数整除(余数为0)。可以整除,说明这个数不是素数,就结束本次MAIN_LOOP循环,也就是不会执行primes[ cnt++] = x;即不把这个数放在素数的数组中。
在这个循环中i是数组下标(不是cnt),则这个for循环不会按照自然数的递增来判断,只需要按照已有的素数是否能判断就行。这是因为小于x的素数的数量当然比自然数的数量小。x自加,连续递增的。
然后遍历输出 for ( int k : primes)
一种从素数的概念出发的思考方式:任何素数的倍数都不是素数。把所有素数的倍数都挑走。
可以构造一个布尔型,把已知素数的倍数,如2的2倍,3倍,n倍的数字都标记为false.然后开始标记3,5(4已经被标记为false)等等。
算法不一定要和人的想法一样
package diwuzhou3;
public class Diwuzhou3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
boolean[] isPrime = new boolean[100];
for( int i=2; 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=0; i< isPrime. length; i++)
{
if ( isPrime[ i])
{
System. out.print( i+ " ");
}
}
}
} 第一个循环,使所有数组的元素变为true.默认是false,但程序需要true。注意这个数组是boolean型的数组(C里边还真没见过),数组元素100个。当然最后输出的素数不是100个,而是100以内的素数。 第二个循环,先把2的倍数(小于100的)全标记为false。标记完了以后,用if ( isPrime[ i]),对下一个没被标记的数字,也就是紧接着是素数的那个数,3,开始进行倍数的标记false。 第三个循环,输出所有标记为true的数。注意这些数字不是放在数组中的,输出的不是数组元素,而是输出i,数组的下标