针对数组的操作
1,在操作数组时经常碰到的两个异常:ArrayIndexOutOfBoundsException和NullPointerException
ArrayIndexOutOfBoundsException:数组角标越界异常
NullPointerException:空指针异常
例:
a.数组角标越界异常:操作数组时,访问到了数组中不存在的角标。
int[] arr = {3,1,6,5,4}; System.out.println(arr[7]);
b.空指针异常:当引用没有任何指向值为null的情况,该引用还在用于操作实体。
int[] arr = new int[3]; arr = null; System.out.println(arr[1]);
2,获取数组中最值
a.获取数组中的最大值
//通过定义一个变量,初始化为数组中任意一个值,通过其他值与之比较,对大于它的值,将新值赋给它,
//作为新的最大值,依次比较得出最大值
public static int getMax(int[] arr)
{
int max = arr[0];
for(int x=1; x<arr.length; x++)
{
if(arr[x]>max)
max = arr[x];
}
return max;
}
/*
获取最大值的另一种方式。
可不可以将临时变量初始化为0呢?可以。这种方式,其实是在初始化为数组中任意一个角标。
*/
public static int getMax_2(int[] arr)
{
int max = 0;
for(int x=1; x<arr.length; x++)
{
if(arr[x]>arr[max])
max = x;
}
return arr[max];
}
b.获取最小值
public static int getMin(int[] arr)
{
int min = 0;
for(int x=1; x<arr.length; x++)
{
if(arr[x]<arr[min])
min = x;
}
return arr[min];
}
3.折半查找
例:在一个有序数组里插入了一个数,保证其插入后有序。现在查找该数在数组中的位置
/*
折半查找。提高效率,但是必须要保证该数组是有序的数组。
*/
public static int halfSearch(int[] arr,int key)
{
int min,max,mid;
min = 0;
max = arr.length-1;
mid = (max+min)/2;
while(arr[mid]!=key)
{
if(key>arr[mid])
min = mid + 1;
else if(key<arr[mid])
max = mid - 1;
if(min>max)
return -1;
mid = (max+min)/2;
}
return mid;
}
/*
折半的第二种方式。
*/
public static int halfSearch_2(int[] arr,int key)
{
int min = 0,max = arr.length-1,mid;
while(min<=max)
{
mid = (max+min)>>1;
if(key>arr[mid])
min = mid + 1;
else if(key<arr[mid])
max = mid - 1;
else
return mid;
}
return -1;
}
注:int x = Arrays.binarySearch(arr,190);//java提供好的一个进行折半查找的功能。开发时使用这个。
4.排序
a.冒泡排序
public static void bubbleSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=0; y<arr.length-x-1; y++)//-x:让每一次比较的元素减少,-1:避免角标越界。
{
if(arr[y]<arr[y+1])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
b.选择排序
public static void selectSort(int[] arr)
{
for (int x=0; x<arr.length-1 ; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
int temp = arr[x];
arr[x] = arr[y];
arr[y]= temp;
}
}
}
}
注:Arrays.sort(arr);//java中已经定义好的一种排序方式。开发中,对数组排序。要使用该句代码。
5.数组反转
//反转函数
public static void reverseArray(int[] arr)
{
for(int start=0,end=arr.length-1; start<end ; start++,end--)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
6.进制转换
/*
十进制-->十六进制。
*/
public static void toHex(int num)
{
StringBuffer sb = new StringBuffer();
for(int x=0; x<8; x++)
{
int temp = num & 15;
if(temp>9)
//System.out.println((char)(temp-10+'A'));
sb.append((char)(temp-10+'A'));
else
//System.out.println(temp);
sb.append(temp);
num = num >>> 4;
}
System.out.println(sb.reverse());
}
注: StringBuffer:线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。
append(char c): 将 char 参数的字符串表示形式追加到此序列。
reverse();将此字符序列用其反转形式取代。
>>>4:表示不带符号的右移四位。
通过新建一个二进制或者十六进制的表,每一次&15后的值作为索引去查建立好的表
0 1 2 3 4 5 6 7 8 9 A B C D E F ==十六进制中的元素。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15查表法:将所有的元素临时存储起来。建立对应关系。
每一次&15后的值作为索引去查建立好的表。就可以找对应的元素。
这样比 -10+'a'简单的多。这个表怎么建立呢?
可以通过数据的形式来定义。发现终于出结果了。但是是反着的。想要正过来呢?可以通过StringBuffer reverse功能来完成。
但是这个工具还没有学习。所以可以使用已经学习过的容器:数组来完成存储。;
public static void toHex(int num) { char[] chs = {'0','1','2','3' ,'4','5','6','7' ,'8','9','A','B' ,'C','D','E','F'}; //定义一个临时容器。 char[] arr = new char[8]; int pos = arr.length; while(num!=0) { int temp = num & 15; //System.out.println(chs[temp]); arr[--pos] = chs[temp]; num = num >>> 4; } System.out.println("pos="+pos); //存储数据的arr数组遍历。 for(int x=pos;x<arr.length; x++) { System.out.print(arr[x]+","); } }
注:对上述代码进行提炼,得出十进制向任意进制转换的功能函数
public static void trans(int num,int base,int offset) { if(num==0) { System.out.println(0); return ; } char[] chs = {'0','1','2','3' ,'4','5','6','7' ,'8','9','A','B' ,'C','D','E','F'}; char[] arr = new char[32]; int pos = arr.length; while(num!=0) { int temp = num & base; arr[--pos] = chs[temp]; num = num >>> offset; } for(int x=pos; x<arr.length; x++) { System.out.print(arr[x]); } return ; }
base指num&的值,十六进制,八进制,二进制分别要&的数为15、7、1。
offset表示右移的位数,十六进制,八进制,二进制分别要>>>4、3、位。
7.二维数组的定义。
int[][] arr = {{3,5,1,7},{2,3,5,8},{6,1,8,2}};
int sum = 0;
for(int x=0; x<arr.length;x++)
{
for(int y=0; y<arr[x].length; y++)
{
sum = sum + arr[x][y];
}
}
System.out.println("sum="+sum);
8.例题:LuckNumber(幸运数字)
把这个问题想成8个小朋友手拉手成一个圈arr[0]到arr[7],从第一个小朋友开始,每数到3有一个小朋友出队arr=0,外面的for循环7次,给7个小朋友赋值为0,表示出队,最后剩下的那个就是LuckNumber了。
class LuckNumber
{
public static void main(String[] args)
{
int[] arr = {1,2,3,4,5,6,7,8};
int pos = -1;
for(int x=0;x<arr.length-1; x++)
{
for(int y=0; y<3;y++)
{
pos++;
if(pos==arr.length)
pos=0;
while(arr[pos]==0)
{
pos++;
if(pos==arr.length)
pos=0;
}
}
arr[pos] = 0;
//System.out.println(arr[pos]);
}
for(int x=0; x<arr.length; x++)
{
if(arr[x]!=0)
{
System.out.println(arr[x]);
break;
}
}
}
}
本文结束,最后一个例题很重要,需揣摩。