1.1.5 数组
在Java中创建一个数组需要三步:声明,创建,初始化数组元素。
在Java数组中double类型变量默认初始值为0.0。数值类型的默认初始值为0,布尔型的默认初始值为false。
我们需要在运行时明确地创建数组的原因是Java编译器在编译时无法知道应该为数组预留多少空间(对原始类型则可以:int, double, boolean, char)
数组一经创建,其大小就是固定的。
double[] a = new double[N];//数组的初始化
典型的数组处理代码:
//找出数组中最大的元素
double max = a[0];
for(int i = 1; i < a.length; i++)
if(a[i] > max)
max = a[i];
//计算数组元素的平均值
int N = a.length;
double sum = 0.0;
for(int i = 0; i < N; i++)
sum += a[i];
double average = sum/N;
//复制数组
int N = a.length;
double[] b = new double[N];
for(int i = 0; i < N; i++)
b[i] = a[i];
//颠倒数组元素顺序
int N = a.length;
for(int i = 0; i < N/2; i++)
{
double temp = a[i];
a[i] = a[N-1-i];
a[N-1-i] = temp;
}
//矩阵相乘(方阵) a[][] * b[][] = c[][]
int N = a.length;
double[][] c = new double[N][N];
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
{
for(int k = 0; k < N; k++)
c[i][j] += a[i][k] * b[k][j];
}
起别名
请注意!如果我们将一个数组变量赋给另一个变量,那么这两个变量将会指向同一个数组,例如:
int[] a = new int[N];
a[i] = 1234;
int[] b = a;
b[i] = 5678;//此时a[i]也将变成5678
如果是想将数组复制一份,则应该按照上面的复制数组的代码,将a中的元素逐一复制到b中。
静态方法
static将这类方法和1.2节的实例方法区别开来。
典型静态方法的实现(表1.1.5):
//计算一个整数的绝对值
public static int abs(int x)
{
if(x < 0) return -x;
else return x;
}
//计算一个浮点数的绝对值
public static double abs(double x)
{
if(x < 0.0) return -x;
else return x;
}
//判定一个数是否为素数
public static boolean isPrime(int N)
{
if(N < 2) return false;
for(int i = 2; i*i<= N; i++)
if(N % i == 0) return false;
return true;
}
//计算平方根(牛顿迭代法)*****why???
public static double sqrt(double c)
{
if(c < 0) return Double.NaN;
double err = 1e-15;//1e-15就是一个科学记数法的数字1x10的-15次方
double t = c;
while(Math.abs(t-c/t) > error * t)
t = (c/t + t) / 2.0;
return t;
}
//计算直角三角形的斜边
public static double hypotenuse(double a, double b)
{return Math.sqrt(a*a,b*b);}
//计算调和级数(见表1.4.5)
public static double H(int N)
{
double sum = 0.0;
for(int i =1; i <= N; i++)
sum += 1.0 / i;
return sum;
}
递归
编写递归代码时最重要的有以下三点:
1. 递归总有一个最简单的情况——方法的第一条语句总是一个包含return的条件语句。
2. 递归调用总是去尝试解决一个规模更小的问题,这样递归才能收敛到最简单的情况。
3. 递归调用的父问题和尝试解决的子问题之间不应该有交集。(EX: 在二分查找的递归实现和快速排序的递归实现中,两个子问题各自操作的数组部分是不同的)
//二分查找的递归实现
public static int rank(int key, int[] a)
{return rank(key, a, 0, a.length - 1);}
public static int rank(int key, int[] a, int lo, int hi)
{ //如果key存在于a[]中,它的索引不会小于lo且不会大于hi
if(lo>hi) return -1;
int mid = lo + (hi-lo)/2;
if(key < a[mid]) return rank(key, a, lo, mid - 1);
else if(key > a[mid]) return rank(ket, a, mid+1, hi);
else return mid;
}